transactions - 2PC vs Sagas(分布式事务)

标签 transactions cloud microservices distributed-computing saga

我正在深入了解分布式系统,以及如何在此类系统中维护数据一致性,其中业务事务涵盖多个服务、有界上下文和网络边界。

以下是我所知道的两种用于实现分布式事务的方法:

  • 两阶段提交 (2PC)
  • 传奇

2PC是一种协议(protocol),应用程序可以在平台的支持下透明地利用全局ACID事务。据我所知,它嵌入在平台中,对业务逻辑和应用程序代码是透明的。

另一方面,Sagas 是一系列本地事务,其中每个本地事务都会改变并保留实体以及指示全局事务阶段的一些标志并提交更改。换句话说,事务状态是域模型的一部分。回滚是指提交一系列“反向”事务。无论哪种情况,服务发出的事件都会触发这些本地事务。

现在,什么时候以及为什么人们会使用 sagas 而不是 2PC,反之亦然?两者的用例和优缺点是什么?特别是,saga 的脆弱性让我感到紧张,因为反向分布式事务也可能失败。

最佳答案

据我了解(不是 2PC 的大用户,因为我认为它有局限性):

  • 通常,2PC 用于即时交易。
  • 通常,Sagas 用于长时间运行事务。

之后用例就很明显了:

  • 2PC 可以允许您在一个请求中提交整个事务,跨系统和网络跨越该请求。假设每个参与系统和网络都遵循该协议(protocol),您可以无缝地提交或回滚整个事务。
  • Saga 允许您将事务拆分为多个步骤,跨越很长一段时间(不一定是系统和网络)。

示例:

  • 2PC:为每个收到的发票请求保存客户,同时由 2 个不同的系统管理。
  • Sagas:预订由多个转机航类组成的航类行程,而每个航类均由不同的航空公司运营。

我个人认为Saga能够做到2PC能做到的事情。反之则不准确。

我认为 Sagas 是通用的,而 2PC 涉及平台/供应商锁定。

更新/添加(可选阅读):

我的答案已经存在一段时间了,我发现这个话题从那时起就获得了一些关注。

我想为那些来到这里并且不确定该走哪条路线的人澄清关于这个主题的几点。

  1. Saga 是一个领域建模(即与技术无关)概念,而 2PC 是一个特定于技术的概念,由一些(可能是许多)供应商实现。打个比方,如果我们将领域事件(裸对象)与消息代理(例如 RabbitMQ)进行比较,这是一样的。
  2. 如果您已经使用了实现此类协议(protocol)的平台,2PC 可能是一个不错的选择。并非所有人都这样做,因此我称其为限制。我看到人们发现了一个论点,即 Saga 更具限制性,因为它更难实现,但这就像说橙子多汁而不是苹果甜一样。两种不同的东西。
  3. 也要考虑人为因素。有些人(开发人员、架构师)是技术极客。他们将业务逻辑或域模型称为样板代码。我属于另一群人,他们认为领域模型是最有值(value)的代码。这种偏好也会影响 Saga 和 2PC 之间的决定,以及谁喜欢什么。我无法解释为什么您应该更喜欢领域驱动的思维而不是技术驱动的解决方案,因为它不适合此页面,您将放弃阅读我的答案。请在网上查找更多信息,也许可以通过我的著作。

@freakish 在评论中提到了一个公平的观点:2PC 更喜欢一致性,而 Saga 将其降级为“最终一致性”。如果您遇到一致性比可用性更重要的情况(请阅读 CAP ),那么也许您确实需要像 2PC 这样的系统事务协议(protocol)。否则,我建议使用 Saga 等商业交易。请阅读系统事务与业务事务,例如在 PEAA .

关于transactions - 2PC vs Sagas(分布式事务),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48906817/

相关文章:

database - 使用 android 平台更新 parse.com 中每行的值

node.js - 当您的所有服务器端代码都是公开的并且没有地方存储您的私钥时,您将如何使用 HyperDev 访问第三方 API?

微服务和 API 网关

java - hibernate : Transaction commited but data not inserted to the Database

hibernate - JBoss TreeCache 作为二级 Hibernate 缓存的并发策略配置

grails - 如果情况下,在不真实的情况下奇怪地调用合并

Jquery Canvas 云插件 - 如何使用 CSS 设置 Canvas 元素的样式

c# - 如果客户端进程在事务开始后被终止,数据库表将保持锁定状态

amazon-web-services - 如何使用 AWS Beanstalk 和 Spring Cloud Netflix 在 Docker 容器之间建立连接

microservices - 如何使用异步请求/响应响应状态代码?