我有一些不同的REST服务,这些服务托管在使用不同数据库的不同服务器上。我有一些RESTful服务,它们在应该是一个事务单元中调用上面的多个这样的服务。如果这些RESTful服务中的任何一个失败,我们最终会遇到数据一致性问题。是否有一种巧妙的架构方式来协调回滚?或者让交易经理走的路?
作为一个简单的例子,RESTful服务1有一个POST请求,它将thingamajig的项目数减少1。 RESTful服务2发送付款。如果服务2失败,我们如何在没有新的RESTful退款服务的情况下干净地实施服务1的回滚(如果必须要这样做,那就没关系)。我正在寻找上述问题的架构答案,这符合REST原则。
答案 0 :(得分:7)
您的回答:https://stackoverflow.com/a/1390393/607033您无法使用事务,因为通过REST,客户端维护客户端状态,服务器维护资源状态。因此,如果您希望客户端维护资源状态,那么它不是REST,因为它会违反stateless constraint。违反无状态约束通常会导致糟糕的可伸缩性。在这种情况下,它将导致错误的水平可伸缩性,因为您必须在实例之间同步正在进行的事务。所以,请不要尝试在REST服务之上构建多阶段提交。
可能的解决方案:
POST /transactions/ {resource: "/forums/12/messages/45", method: "PUT", data: "..."}
和POST /transactions/1/commit
代替PUT /forums/12/messages/45
答案 1 :(得分:1)
分布式事务很复杂,需要每个参与系统都支持回滚的概念。对于您的服务,他们每个人都必须支持某种形式的回滚。在分布式系统中协调类似这样的事情可能不实用或不可取用同步方式。在这种情况下,您可能希望异步回滚,系统最终会在未来某个时间点达到一致性。显然还有很多其他细节(超时,错误处理,重试等)。
有关最终一致性的更多详细信息,请查看维基百科条目here。
答案 2 :(得分:0)
基本上问题是你需要在一个环境(HTTP)中使用默认情况下不是事务性的事务 - 在DB意义上(因为在HTTP中事务是一个成功的请求 - 响应周期)。
@leeor响应的内容完全正确,我想添加的是我如何从设计网站解决问题。
所以你需要一个端点,可能是/transactions
。通过POST
方法,您可以添加一个不可变的新事务(包含所有必需的详细信息) - 创建后,您只能通过GET
方法询问数据/状态。可以更新事务状态/数据的只是服务器本身。
在幕后(在创建事务期间),应创建参与事务的每个资源的快照(稍后可以反转)。然后应该开始执行所有操作,如果发生任何故障,应该反转所有快照。你没有提到任何技术,所以很难提出合理的建议。您需要的是全面的日志记录。