两阶段提交

don*_*gcn 58 database distributed-transactions

我相信大多数人都知道2PC(两阶段提交协议)是什么以及如何在Java或大多数现代语言中使用它.基本上,当您有2个或更多DB时,它用于确保事务处于同步状态.

假设我有两个DB(A和B)在两个不同的位置使用2PC.在A和B准备提交事务之前,两个DB都将向事务管理器报告,说它们已准备好提交.因此,当事务管理器被确认时,它将向A和B发送信号,告诉它们继续.

这是我的问题:让我们说A收到信号并提交交易.一切都完成后,B即将做同样的事情,但有人拔掉电源线,导致整个服务器关闭.当B重新上线时,B会做什么?B怎么做呢?

记住,A是承诺但B不是,我们正在使用2PC(因此,2PC的设计停止工作,不是吗?)

Con*_*lls 66

论两阶段承诺

两阶段提交不保证分布式事务不会失败,但它确保它不会在TM没有意识到的情况下以静默方式失败.

为了让B到报告这项交易为准备提交,B必须在永久存储的交易(即B必须是能够保证交易能够在所有情况下提交).在这种情况下,B持有该事务,但事务管理器尚未收到来自B的消息,确认B已完成提交.

当B重新联机并要求其提交交易时,事务管理器将再次轮询B. 如果B已经提交了事务,它将报告事务为已提交.如果B尚未提交事务,则它将继续提交,因为它已经持久化,因此仍然可以提交事务.

为了使B在这种情况下失败,它将不得不经历失去数据或日志条目的灾难性故障.事务管理器仍然会知道B没有报告成功提交.1

实际上,如果B不再提交事务,则意味着B out的灾难导致数据丢失,当TM要求它提交它不知道的TxID时,B会报告错误或没想到处于可以承诺的状态.

因此,两阶段提交不会阻止发生灾难性故障,但它确实可以防止故障被忽视.在这种情况下,如果B无法提交,事务管理器将向应用程序报告错误.

应用程序仍然必须能够从错误中恢复,但是事务不会在应用程序无法识别不一致状态的情况下以静默方式失败.

语义

  • 如果资源管理器或网络在阶段1中发生故障,则事务管理器将检测到致命错误(无法连接到资源管理器)并将子事务标记为失败.当网络恢复时,它将中止所有参与资源管理器上的事务.

  • 如果资源管理器或网络在阶段2中关闭,则事务管理器将继续轮询资源管理器,直到它恢复.当它重新连接回资源管理器时,它将告诉RM提交事务.如果RM返回"未知TxID"行的错误,则TM将意识到RM中存在数据丢失问题.

  • 如果TM在阶段1中关闭,则客户端将阻塞,直到TM恢复,除非由于网络连接中断而超时或收到错误.在这种情况下,客户端会知道错误,可以重新尝试或启动中止本身.

  • 如果TM在阶段2中关闭,那么它将阻止客户端直到TM恢复.它已经将事务报告为可提交的,并且不应向客户端提供致命错误,尽管它可能会阻止,直到TM恢复.TM仍将处于未提交状态的事务,并将在RM重新启动时轮询RM.

资源管理器中的提交后数据丢失事件不由事务管理器处理,并且是RM的弹性的函数.

两阶段提交并不能保证容错-看到的Paxos为确实解决容错协议的例子-但它确实保证分布式事务的那部分失效不能去未注意到的.

  1. 请注意,此类故障也可能会丢失先前提交的事务中的数据.两阶段提交不保证资源管理器不会丢失或损坏数据或DR程序不会搞砸.

  • 不要将 2PC 语义与容错混淆。TM 仍会将事务标记为未提交,直到它在第二阶段收到所有提交的确认。当它恢复时,它将轮询所有资源管理器并要求他们提交,他们将报告事务已提交。请记住,RM 必须能够保证提交。2PC 在报告第二阶段成功提交后,或之后的任何时间,对 RM 的灾难性故障不做任何处理。 (2认同)