为啥两阶段提交被认为是原子的?
Posted
技术标签:
【中文标题】为啥两阶段提交被认为是原子的?【英文标题】:Why is two-phase commit considered atomic?为什么两阶段提交被认为是原子的? 【发布时间】:2016-06-07 18:09:25 【问题描述】:两阶段提交被描述为“原子提交协议”。我希望这意味着所有客户端都可以在事务提交之前或提交之后看到世界的状态——没有中间状态。虽然它似乎可以进入事务部分提交并且客户端看到不一致的数据,从而破坏原子性的状态。
考虑两个数据库 A 和 B 的情况。如果在 A 已提交但 B 已提交之前的提交阶段存在分区,则事务是部分提交的。查询 A 和 B 的用户将不会看到一致的数据 - 事务已在 A 上提交,但 B 有提交之前的数据。
ACID 的“一致”部分似乎也被破坏了——查询 A 和 B 的客户端可能会看到违反业务规则的数据。
我猜这个想法是,当分区结束并且事务管理器指示 B 提交时,系统最终能够从中恢复。但与此同时,系统处于不一致的“部分提交”状态。原子性的全部目的不是防止这种情况发生吗?当一致性恢复时,损坏可能已经造成。
当说两阶段提交是原子的时,指的是什么属性?
【问题讨论】:
How ACID is the two-phase commit protocol?的可能重复 我认为这是隔离级别的问题。在可重复读取下方,您可以看到提交事务之前的一些数据,以及提交事务之后的一些数据。只要没有脏读,它仍然被认为是 ACID(即使使用非分布式数据库也可能发生这种情况)。通常不需要隔离级别 Serializable。 另一个问题的答案是“2PC 真的只承诺一个操作是原子的”。我的问题是为什么它看起来不是原子的时被认为是原子的。 2pc 提供的“原子性”是什么? 答案还说“2PC 不能适应所有故障场景”,并且会破坏四种 ACID 中的每一种。例如,如果您在中间关闭 B,它可能尚未提交(而 A 已提交),并且将在恢复期间回滚,因此您最终会出现不一致的状态。但除此之外,它是“原子的”:整个事务将被提交,或者一个都不提交。结果如何对其他事务可见是一个隔离问题。 【参考方案1】:Atomic 意味着要么操作会产生一些效果,要么系统将保持相同的状态。 2PC 算法的工作原理是首先协调器要求所有分布式机器到prepare
进行交易。在收到Yes
后,它会发送命令以提交事务。
如果协调器只收到所有机器的成功,那么事务就完成了,否则如果之后出现网络中断或任何其他问题,那么您将陷入两将问题的问题强>。它的原子性与分布式系统一样多。
一致性只能通过隔离级别来实现。是否允许读取,是否允许脏读。
【讨论】:
【参考方案2】:我没有这方面的学术背景,但根据我的实践经验(我是 Narayana 项目的 QE),2PC 没有被称为 ACID。它只确保事务是原子的。原子,一切或一切都已完成。
我认为你在你的问题中很好地解决了 2PC 的限制。
由于事务分布在更多的 DB/JMS 代理/...上,因此无法保证它们会相互隔离。如前所述,事务管理器仅管理资源并说明何时准备(锁定)以及何时提交。例如,如果事务管理器和第二个资源之间的连接在第一个资源已经提交的提交阶段被关闭,那么是的,您可以在第一个资源上看到已经提交的数据,但是在连接建立后将处理第二个等待提交的数据。但是你可以确保它最终会被提交。 (可能)在特定资源级别确保隔离(所有使用第二个资源上的数据的事务都将被隔离)。
另一方面,我认为一致性并没有被打破。一致性意味着事务根据定义的规则将系统从一个有效状态带到另一个有效状态。系统将在事务开始和事务结束时保持一致。
正如 ACID 所述 (https://en.wikipedia.org/wiki/ACID),通常情况下,即使是 DB 事务也会默认放宽隔离 ACID 属性。大多数数据库使用 READ COMMITTED 作为默认隔离级别,它确实可以保护您所有的麻烦(当取决于数据库实现时,可能会发生不可重复读取和幻读)。
【讨论】:
我偶然回到了这个问题。我想在这里加强我的回应。问题在于该问题混合了 ACID 一致性和 CAP 一致性的概念。原子性定义事务全部提交或全部中止。在事务执行期间没有其他关于部分结果的信息。一致性说:“在事务完成时,数据库结构上是健全的”。我会指出“完成时”。含糊之处在于 CAP 的一致性表示:“所有节点看到的所有读写执行都是原子的”。以上是关于为啥两阶段提交被认为是原子的?的主要内容,如果未能解决你的问题,请参考以下文章