2PC是Two Phase Commitment Protocol的缩写,也就是二阶段提交。
1978年,Jim Gray等人提出了2PC协议,用于协调分布式系统中的事务提交。
1979年,Jim Gray在《Notes on Database Operating Systems》提及到2PC
1993年,Jim Gray和Andreas Reuter?合作写了一部事务处理的经典书籍“Transaction Processing:Concepts and Techniques”《事务处理:概念和技术》
3PC是Three Phase Commitment Protocol的缩写,也就是三阶段提交。
对于2PC的缺点,Skeen和Stonebraker?在1983年出版了“A Formal Model of Crash Recovery in a Distributed System”(分布式系统中故障恢复的自适应模型(自己翻译的))
2PC | 3PC | |
---|---|---|
阶段 | 2个阶段:prepare准备阶段与commit提交阶段 | 3个阶段:CanCommit能否提交阶段,PreCommit准备提交阶段,DoCommit事务提交阶段 |
复杂程度 | 简单 | 复杂 |
一致性 | 好 | 较低 |
可用性 | 较低 | 高 |
资源损耗 | 高 | 低 |
协调者(Coordinator)是事务的发起者
在实际的使用过程中,TM作为协调者。TM(Transaction Manager)是定义的一种软件组件,有着分布式事务的管理职责,对分布式事务进行协调和执行。
参与者(Cohort)是事务的执行者
在实际的使用过程中,使用RM作为参与者。RM(Resource Manager)是定义的一种软件组件,它在分布式系统当中对资源负责管理和控制,能够进行资源的锁定、解锁、回滚和提交等操作。
两阶段提交是一种原子性提交协议,它通过将事务的提交过程分为两个阶段来确保分布式事务的一致性。简单来说,2PC协议包括一个协调者(Coordinator)和多个参与者(Participants, 或cohorts)。协调者负责引导整个提交过程,而参与者负责执行事务操作。
(1)在准备阶段中,协调者会向所有参与者节点发送准备请求,询问是否可以执行事务提交操作。
(2)在参与者节点执行完(本地的Undo/Redo日志)事务之后,会向协调者发送准备完成的消息。
(3)协调者会在收到所有参与者的准备完成消息后,判断是否所有节点都准备好了,如果有一个节点没有准备好,那么协调者会发送回滚请求,要求所有节点回滚事务。
(1)在提交阶段中,如果所有参与者都准备好了,那么协调者会向所有参与者发送提交请求
(2)在参与者节点执行完提交操作后,会正式执行事务提交操作,完成后释放事务资源
(3)向协调者发送提交完成的ACK消息。
(4)协调者会在收到所有参与者的提交完成消息后,完成事务提交。
有参与者失败,则向协调者反馈NO的消息,或者等待时间过长,协调者就会中断事务
(1)引入超时机制。同时在协调者和参与者中都引入超时机制。
(2)在第一阶段和第二阶段中多了一个中间状态阶段,也就是准备阶段。保证了在最后提交阶段之前各参与者节点的状态是一致的。三阶段提交分别为CanCommit、PreCommit、DoCommit三个阶段。
(1)事务询问 ,协调者向所有的参与者发送CanCommit请求。询问是否可以执行事务提交操作。然后开始等待参与者的响应。
(2)各参与者向协调者进行响应反馈(并不是执行) ,参与者接到CanCommit请求之后,认为是正常的,可以顺利执行事务,则返回Yes响应,并进入预备状态。否则反馈No
根据参与者的反馈结果,协调者来决定是否可以继续事务的PreCommit操作。有以下两种情况。
协调者从每个参与者获得的反馈都是Yes响应,就会执行事务的预执行。
1.发送预提交请求 ,协调者向每个参与者发送PreCommit请求。
2.事务预提交 ,参与者接收到PreCommit请求后,会执行事务操作,并将undo和redo信息记录到事务日志中。
3.响应反馈 ,参与者成功的执行了事务操作,并将ACK响应返回,同时开始等待最终指令。
有任何一个参与者向协调者发送了No响应,或者等待超时之后,协调者都没有接到参与者的响应,就执行事务的中断。
1.发送中断请求, 协调者向每个参与者发送abort请求。
2.中断事务 ,参与者收到来自协调者的abort请求之后(或超时之后,仍未收到协调者的请求),执行事务的中断。
当预提交成功执行后,也有两种情况。
(1)发送提交请求, 协调接收到参与者发送的ACK响应,从预提交状态进入到提交状态。并向每个参与者发送doCommit请求。
(2)事务提交, 参与者接收到doCommit请求之后,正式执行事务提交。并在完成事务提交之后释放所有事务资源。
(3)响应反馈 ,事务提交完之后,向协调者发送Ack响应。
(4)完成事务, 协调者接收到每个参与者的ack响应之后,完成事务。
协调者没有接收到参与者发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。
(1)发送中断请求, 协调者向每个参与者发送abort请求
(2)事务回滚 ,每个参与者接收到abort请求之后,利用PreCommit记录的undo信息来执行事务的回滚操作,并在完成回滚之后释放所有的事务资源。
(3)反馈结果, 参与者完成事务回滚之后,向协调者发送ACK响应
(4)中断事务 ,协调者接收到参与者反馈的ACK消息之后,执行事务的中断。
对于2PC来说,3PC有以下好处:
(1)3PC减少了资源的使用,因为在CanCommit阶段,并没有进行真正执行事务。
(2)3PC减少了数据不一致的发生概率,因为在CanCommit阶段,并没有进行真正执行事务,即使失败也不会影响数据
但是缺点也很明显:
(1)2个阶段,变成3个阶段后,实际的实现更加复杂。
(2)2PC存在的协调者出现问题的话,导致阻塞与数据不一致,3PC仍然存在,只是概率小了一点