当使用ajax或从移动设备或其他设备发布数据时,通常会出现“重试”情况,因此如果发生超时,数据将再次发布。
这真的是个好主意吗?
post数据本来就是等幂的,所以如果
发邮件到服务器,
服务器接收请求,
执行和
然后将数据发送回
如果超时时间是在3点以后。然后下一次重试将发送原本是等幂的数据。
那么问题是,应该为post数据设置重试(从客户端调用时),还是应该将服务器设计为始终适当地处理post数据(使用令牌等),或者我遗漏了什么?
根据问题更新-这是一个移动应用程序。碰巧,在测试过程中注意到超时时间太短,应用程序将重试。同时,后端服务器实际上已经接受并处理了最初的请求,当新的(其他相同的)重新请求传入时,V.upset感到不安。
最佳答案
nonce
是对此的(部分)解决方案。服务器生成一个nonce并将其提供给客户端。客户端发送包含nonce的POST
,服务器检查nonce是否有效且未使用,如果有效,则对POST
执行操作并使nonce无效,如果无效,则报告nonce已使用并丢弃数据。用户点击两次提交按钮,也很有用地避免了“双重发布”的问题。
但是,它正在将问题从客户端转移到服务器上的其他客户端。如果在操作之前使nonce失效,则操作可能仍然失败/挂起;如果在操作之后使其失效,则nonce对于处理过程中的请求仍然有效。因此,服务器上的一个可能场景变成了接收。
锁定nonce
采取行动
在任何阻止操作完成、回滚和释放nonce上的锁的处理错误上。
如果没有错误,则使nonce无效/删除nonce。
Semaphores在服务器端,这是最有用的,大多数后端语言都有这些库。
所以,实现所有这些:
可以安全地重试,如果操作已经执行,则不会再次执行。
一个表示nonce已经被使用的回复可以理解为一个确认原始邮件已经被执行的确认。
如果需要第二个请求显示第一个请求通过的操作的结果,则需要服务器端的短期缓存。
取决于你对随后的尝试设定一个合理的限制(如果第二次失败怎么办?还是第三个?)是的。