REST和事务回滚

cva*_*vam 6 rest transactions

我有一些不同的REST服务,它们托管在使用不同DB的不同服务器上.我有一些RESTful服务,它们在应该是一个事务单元中调用上面的多个这样的服务.如果这些RESTful服务中的任何一个失败,我们最终会遇到数据一致性问题.是否有一种巧妙的架构方式来协调回滚?或者让交易经理走的路?

作为一个简单的例子,RESTful服务1有一个POST请求,它将thingamajig的项目数减少1. RESTful service 2 POST一个付款.如果服务2失败,我们如何在没有新的RESTful退款服务的情况下干净地实施服务1的回滚(如果必须要这样做,那就没关系).我正在寻找上述问题的架构答案,这符合REST原则.

inf*_*rno 7

您的回答:https://stackoverflow.com/a/1390393/607033您无法使用事务,因为通过REST,客户端维护客户端状态,服务器维护资源状态.因此,如果您希望客户端维护资源状态,那么它不是REST,因为它会违反无状态约束.违反无状态约束通常会导致糟糕的可伸缩性.在这种情况下,它将导致错误的水平可伸缩性,因为您必须在实例之间同步正在进行的事务.所以,请不要尝试在REST服务之上构建多阶段提交.

可能的解决方案:

  • 您可以坚持立即一致性,只使用一个Web服务而不是两个.通过数据库,文件系统等资源,多阶段提交是必需的.当您分解更大的REST服务并将这些资源的使用转移到多个较小的REST服务中时,如果您错误地执行此拆分,则可能会出现问题.这是因为其中一个REST服务将需要一个它无权访问的资源,因此必须使用另一个REST服务来访问该资源.这将迫使多阶段提交代码移动到更高的抽象级别,达到REST服务的级别.您可以通过合并这两个REST服务并将代码移动到它所属的较低抽象级别来解决此问题.
  • 使用REST与最终一致性的另一种解决方法,以便您可以立即接受202响应,并且您可以稍后处理接受的请求.如果选择此解决方案,则必须通过开发应用程序来了解REST服务并非始终保持同步.OFC.此方法仅适用于内部REST服务,通过该服务,您可以确保客户端在REST服务不可用时重试,因此,如果您编写并运行客户端代码.
  • 另一种可能是将每个事务存储为资源的最丑陋的解决方法,因此您可以POST提交和回滚.我认为这种可能的解决方案不可行,因为它会违反统一的接口约束.我们会使用POST /transactions/ {resource: "/forums/12/messages/45", method: "PUT", data: "..."}POST /transactions/1/commit不是例如PUT /forums/12/messages/45


lee*_*eor 6

分布式事务很复杂,需要每个参与系统支持回滚的概念。就您的服务而言,它们都必须支持某种形式的回滚。在分布式系统中以同步方式协调类似的事情可能不切实际或不建议。在这种情况下,您可能希望异步回滚,并且系统最终会在未来的某个时刻达到一致性。显然还有许多其他细节(超时、错误处理、重试等)。

有关最终一致性的更多详细信息,请查看此处的维基百科条目。