Web services 处理重复POST请求引起的副作用

Web services 处理重复POST请求引起的副作用,web-services,rest,post,duplicates,idempotent,Web Services,Rest,Post,Duplicates,Idempotent,假设我们有一个web服务,可以创建和更新会议室预订。更新可以更改预订的各个方面,例如时间和房间号 假设用户与服务的网络连接可能不可靠(例如移动网络),两个用户A和B尝试按顺序更新同一预订 用户A发送POST请求将会议时间更改为下午2点,请求到达服务器,服务器成功地处理了请求。但是,由于网络连接,返回给用户A的响应丢失,用户A认为请求失败 在用户A再次尝试之前,用户B发送将会议时间更改为下午2:30的请求,并成功响应用户B 现在,用户A再次重试(可能自动地)相同的请求,这次请求和响应都成功了,没有

假设我们有一个web服务,可以创建和更新会议室预订。更新可以更改预订的各个方面,例如时间和房间号

假设用户与服务的网络连接可能不可靠(例如移动网络),两个用户A和B尝试按顺序更新同一预订

用户A发送POST请求将会议时间更改为下午2点,请求到达服务器,服务器成功地处理了请求。但是,由于网络连接,返回给用户A的响应丢失,用户A认为请求失败

在用户A再次尝试之前,用户B发送将会议时间更改为下午2:30的请求,并成功响应用户B

现在,用户A再次重试(可能自动地)相同的请求,这次请求和响应都成功了,没有问题。换句话说,会议时间改回下午2点

在上面的假设场景中,用户A的重复请求会导致用户B的请求被覆盖,并导致服务器端出现错误状态

一个可能但简单的解决方案是为客户端上的每个请求设置一个ID,如果请求只是重新尝试/发送,则该ID不会更改。然后在服务器端,服务器维护接收到的请求ID的集合,并检查重复的请求ID


解决此问题的更好技术或方法是什么?

这是并发用户的常见问题。解决此问题的一种方法是强制执行条件请求,要求客户端发送
(如果自
以来未修改)标头,其中包含其试图更改的资源的
上次修改的
值。这保证了从上次检查到现在没有其他人改变它。在您的情况下,这将防止A覆盖B的更改

例如,用户A想要更改会议时间。它发送会议资源的GET请求,并保留上次修改的
响应头的值。然后,它发送
POST
请求,如果自
头以来未修改,则发送
头中上次修改的
值。按照您的示例,此请求实际上成功,但响应丢失

如果A立即重复请求,它将失败,因为该条件不再有效


如果同时B做同样的事情并再次更改会议时间,当A尝试重复请求时,没有检查与B更改相对应的当前
上次修改的
值,它也会失败,因为
412前提条件失败

查看PRG()是否可以帮助您。谢谢您的回答。在这种情况下,如果自
和上次修改以来未修改,请详细说明
的用法?哪一方设置了哪一个头?那么这是否意味着,在服务器端,每次更新时都需要更新资源的时间戳(在本例中为每次会议的详细信息)?当任何客户端发送一个POST请求时,如果在
头字段中有自己版本的
上次修改的
值(如果自
头字段未修改),服务器将根据所请求资源的存储时间戳检查该值。如果时间戳在上次修改的
值之后,则服务器不应处理该请求,并应响应
412前提条件失败
。这种理解正确吗?客户端不发送其自己版本的上次修改的
。它应该发出GET请求,并在POST请求的
头中使用该响应中返回的值(如果未修改)。如果当前存储的时间戳在
之后,如果自
值以来未修改,则服务器应失败,并出现
412前置条件失败
。如果客户端未发送
(如果自
标头以来未修改),则服务器应在
428所需前提条件下失败。