我正在添加我的回答,以解决sagas和2PC之间的主要差异,即一致性模型。
另一方面,sagas是一系列本地事务,其中每个本地事务改变并持久化实体以及一些标志,指示全局事务的阶段并提交更改。
有趣的描述。这个标志到底是什么?每个节点是否应该在全局事务完成后提交更改(并由此跟踪)?每个节点将本地更改保持对外不可见,直到发生这种情况?如果是这样,那么它与2PC有何不同?如果不是这种情况,那么这个标志又是用来做什么的?
总的来说,据我所知,saga是一系列本地事务。如果序列中的任何节点失败,则流程将被反转,并且每个节点会按相反的顺序生成补偿事务。
然而,使用这个想法我们会遇到几个问题:第一个问题是你自己已经注意到的:如果补偿事务失败怎么办?如果在任何步骤上的任何通信失败怎么办?但还有更多,使用这种方法可以进行脏读取。例如,Node1成功了,而Node2失败了。然后我们在Node1上发出补偿事务。但是,如果另一个进程在Node1更新后但在补偿事务撤消该更新之前读取数据怎么办?潜在的不一致性(取决于您的要求)。
总的来说,sagas是:通过设计最终一致且高效(无全局资源锁定)。如果您对所有节点具有完全控制,则可以使saga变得强烈一致,但这需要大量手动(并且不明显,例如通信问题)的工作,并且可能需要一些资源锁定(因此我们将失去性能)。在这种情况下,为什么不一开始就使用2PC?
另一方面,2PC通过设计是强一致的,这使得它由于资源锁定而可能效率较低。
那么应该使用哪个?这取决于您的要求。如果需要强一致性,则使用2PC。如果不需要,则saga是一个有效的选择,可能更高效。
例如1。假设您创建了一个会计系统,用户可以在帐户之间转移资金。假设这些帐户位于单独的系统上。此外,您有一个严格的要求,即余额始终应为非负数(您不想处理隐含的债务),可能还有一个严格的要求,即最大金额可以设置且不能超过(考虑用于偿还债务的专用帐户:您不能放入比整个债务更多的钱)。那么saga可能不是您想要的,因为由于脏读取(和其他一致性现象),我们可能会得到超出允许范围的余额。2PC在这里将是一个更容易的选择。
例如2。同样,您拥有一个会计系统。但是这次允许超出范围的余额(谁拥有该系统将手动处理)。在这种情况下,也许saga更好。因为手动处理非常少量的问题状态可能比始终保持强一致性更便宜。