处理重复 POST 请求引起的副作用
Handle side effects caused by duplicate POST requests
假设我们有一个创建和更新会议室预订的 Web 服务。更新可以更改预订的各个方面,例如时间和房间号。
假设用户与服务的网络连接可能不可靠(例如移动网络),并且两个用户 A 和 B 尝试按顺序更新同一个预订。
用户A发送POST请求将会议时间更改为下午2点,请求到达服务器,服务器成功处理请求。但是返回给用户A的响应由于网络连接丢失,用户A认为请求失败。
在用户 A 再次尝试之前,用户 B 发送了她将会议时间更改为 2:30pm 的请求,并且成功并成功响应了用户 B。
现在用户 A 再次重试(可能是自动)同一个请求,这次请求和响应都成功了,没有问题。也就是说,会议时间改回下午2点。
在上述假设场景中,用户 A 的重复请求导致用户 B 的请求被覆盖,并导致 server-side 上的状态不正确。
一个可能但天真的解决方案是为客户端上的每个请求设置一个 ID,如果请求只是 re-tried/re-sent,则此 ID 不会改变。然后在 server-side 上,服务器维护 collection 收到的请求 ID 并检查重复项。
解决这个问题有什么更好的技术或方法?
这是并发用户的常见问题。解决它的一种方法是强制执行条件请求,要求客户端发送 If-Unmodified-Since
header 和他们试图更改的资源的 Last-Modified
值。这保证在他们上次检查和现在之间没有其他人更改它。在您的情况下,这将防止 A 覆盖 B 的更改。
比如用户A想更改会议时间。它发送会议资源的 GET 请求并保留 Last-Modified
响应 header 的值。然后,它在 If-Unmodified-Since
header 中发送带有 Last-Modified
值的 POST
请求。按照你的例子,这个请求实际上成功了,但是响应丢失了。
如果 A 立即重复请求,它将失败 412 Precondition Failed
,因为条件不再有效。
如果同时 B 做同样的事情并再次更改会议时间,当 A 尝试重复请求时,没有检查与 B 的更改对应的当前 Last-Modified
值,它也会失败 412 Precondition Failed
.
假设我们有一个创建和更新会议室预订的 Web 服务。更新可以更改预订的各个方面,例如时间和房间号。
假设用户与服务的网络连接可能不可靠(例如移动网络),并且两个用户 A 和 B 尝试按顺序更新同一个预订。
用户A发送POST请求将会议时间更改为下午2点,请求到达服务器,服务器成功处理请求。但是返回给用户A的响应由于网络连接丢失,用户A认为请求失败。
在用户 A 再次尝试之前,用户 B 发送了她将会议时间更改为 2:30pm 的请求,并且成功并成功响应了用户 B。
现在用户 A 再次重试(可能是自动)同一个请求,这次请求和响应都成功了,没有问题。也就是说,会议时间改回下午2点。
在上述假设场景中,用户 A 的重复请求导致用户 B 的请求被覆盖,并导致 server-side 上的状态不正确。
一个可能但天真的解决方案是为客户端上的每个请求设置一个 ID,如果请求只是 re-tried/re-sent,则此 ID 不会改变。然后在 server-side 上,服务器维护 collection 收到的请求 ID 并检查重复项。
解决这个问题有什么更好的技术或方法?
这是并发用户的常见问题。解决它的一种方法是强制执行条件请求,要求客户端发送 If-Unmodified-Since
header 和他们试图更改的资源的 Last-Modified
值。这保证在他们上次检查和现在之间没有其他人更改它。在您的情况下,这将防止 A 覆盖 B 的更改。
比如用户A想更改会议时间。它发送会议资源的 GET 请求并保留 Last-Modified
响应 header 的值。然后,它在 If-Unmodified-Since
header 中发送带有 Last-Modified
值的 POST
请求。按照你的例子,这个请求实际上成功了,但是响应丢失了。
如果 A 立即重复请求,它将失败 412 Precondition Failed
,因为条件不再有效。
如果同时 B 做同样的事情并再次更改会议时间,当 A 尝试重复请求时,没有检查与 B 的更改对应的当前 Last-Modified
值,它也会失败 412 Precondition Failed
.