这是我的 RESTful Web 应用程序中发生的事情:
- HTTP 请求进来
- 应用程序开始构建响应,其中包含一些初始数据部分
- 另一个请求更改了步骤 2 中使用的数据
- 第一个请求就知道数据过期了
它应该怎么做?请求失败并向客户端返回错误?还是应该从头开始(花费比客户预期更多的时间)?
这是我的 RESTful Web 应用程序中发生的事情:
它应该怎么做?请求失败并向客户端返回错误?还是应该从头开始(花费比客户预期更多的时间)?
恕我直言,您应该非常接近对待数据库事务的方式来处理 REST 请求:
很多时候,这实际上可以传递给数据库事务 - 取决于您的请求所做的非数据库工作的数量和内容。
我认为一个很好的起点是 CouchDB 使用的并发模型。在本质上:
更多阅读:
http://wiki.apache.org/couchdb/Technical%20Overview#ACID_Properties http://wiki.apache.org/couchdb/HTTP_Document_API#PUT
假设它与数据库事务无关,并说每个步骤都涉及分布式长时间运行的进程。
在这种情况下,应向客户端发送适当的响应(例如 409/410 http 代码),其中包含表明此请求不再有效且客户端应重试的详细信息。重试可能会陷入循环,或者最坏的情况最终会导致客户不知道。
例如,当您在线预订酒店/机票时,您会收到回复说价格已更改,您需要再次提交以使用新价格购买。
从我的角度来看,您的问题与以下相同:
“如果我尝试从数据库中读取,而另一个事务尝试写入,它将阻塞。但是当我完成读取时,我会错过新数据将由我读取后传入的新事务填充。”
这是一种不好的思考方式。您应该确保客户端在响应中获得一致的数据。如果在他们得到响应时数据已经更新,则不是原始方法的问题。
您的问题是数据当前已更新,我碰巧知道。如果在响应传出网络后立即更新数据怎么办?
恕我直言,选择适合您要求的最简单的解决方案。
客户端应该更频繁地“轮询”以确保他们始终拥有最新的数据副本
严格来说,比赛条件是一个错误。竞争条件的解决方案是没有共享数据。如果对于给定的用例不能避免这种情况,那么先到先得的原则通常会有所帮助:
第一个请求锁定共享数据,第二个请求等待第一个请求完成。