分布式事务-03:3PC 三阶段提交协议实现过程及原理

2022-05-07 17:08:49 浏览数 (1)

摘要:本文主要讲解分布式事务中三阶段提交协议(3pc)相关基础概念、原理及详细的执行过程。

上一篇:分布式事务-02:2PC 二阶段提交协议实现过程及原理

1.理论基础

三阶段提交(Three-phase commit),也叫三阶段提交协议(Three-phase commit protocol),可以看作是二阶段提交(2PC)的改进版本。 

与两阶段提交不同的是,三阶段提交有两个改动点:

1)引入超时机制。同时在协调者和参与者中都引入超时机制。

2)在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。

除了引入超时机制之外,3PC把2PC的准备阶段再次一分为二,这样三阶段提交就有CanCommit、PreCommit、DoCommit三个阶段。 

在第一阶段,只是询问所有参与者是否可以执行事务操作,并不在本阶段执行事务操作。当协调者收到所有的参与者都返回YES时,在第二阶段才执行事务操作,然后在第三阶段执行commit或者rollback。

2. 3pc实现

2.1CanCommit阶段

3PC的CanCommit阶段其实和2PC的准备阶段很像。协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。  这个阶段又可以细分为2个步骤:

  • 1)事务询问 :协调者向参与者发送CanCommit请求。询问是否可以执行事务操作,并不在本地执行事务操作。然后开始等待参与者的响应。 
  • 2)响应反馈 :参与者接到CanCommit请求之后,正常情况下,如果其自身认为可以顺利执行事务,则返回Yes响应,并进入预备状态,否则反馈No。 

2.2PreCommit阶段

协调者根据参与者的反应情况来决定是否可以进行事务的PreCommit操作。根据响应情况,有以下两种可能:

1)假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务的预执行:

1.发送预提交请求: 协调者向参与者发送PreCommit请求,并进入Prepared阶段。

2.事务预提交:参与者接收到PreCommit请求后,会执行事务操作,并将undo和redo信息记录到事务日志中。

3.响应反馈: 如果参与者成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令。

2)假如有任何一个参与者向协调者发送了No响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断。 

1.发送中断请求: 协调者向所有参与者发送abort请求。 

2.中断事务: 参与者收到来自协调者的abort请求之后(或超时之后,仍未收到协调者的请求),执行事务的中断。 

2.3doCommit阶段

该阶段进行真正的事务提交,也可以分为以下两种情况。

1)执行提交

1.发送提交请求 

协调接收到参与者发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有参与者发送doCommit请求。

2.事务提交

参与者接收到doCommit请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源。

3.响应反馈 

事务提交完之后,向协调者发送ACK响应。

4.完成事务 

协调者接收到所有参与者的ACK响应之后,完成事务。

2)中断事务

协调者没有接收到参与者发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。

1.发送中断请求 

协调者向所有参与者发送abort请求。

2.事务回滚 

参与者接收到abort请求之后,利用其在阶段二记录的undo信息来执行事务的回滚操作,并在完成回滚之后释放所有的事务资源。

3.反馈结果 

参与者完成事务回滚之后,向协调者发送ACK消息。

4.中断事务 

协调者接收到参与者反馈的ACK消息之后,执行事务的中断。 

在doCommit阶段,如果参与者无法及时接收到来自协调者的doCommit或者rebort请求时,会在等待超时之后,会继续进行事务的提交。

这里需要注意:当进入第三阶段时,说明参与者在第二阶段已经收到了PreCommit请求,那么协调者产生PreCommit请求的前提条件是他在第二阶段开始之前,收到所有参与者的CanCommit响应都是Yes。一旦参与者收到了PreCommit,意味他知道大家其实都同意修改了)所以,一句话概括就是,当进入第三阶段时,由于网络超时等原因,虽然参与者没有收到commit或者abort响应,但是他有理由相信:成功提交的几率很大。 

3.3pc优缺点

相对于2PC,3PC主要解决的单点故障问题,并减少阻塞,因为一旦参与者无法及时收到来自协调者的信息之后,他会默认执行commit,而不会一直持有事务资源并处于阻塞状态。但是这种机制也会导致数据一致性问题,因为,由于网络原因,协调者发送的abort响应没有及时被参与者接收到,那么参与者在等待超时之后执行了commit操作。这样就和其他接到abort命令并执行回滚的参与者之间存在数据不一致的情况。  

本文部分内容参考:https://www.bytesoft.org/

0 人点赞