分布式事务 之 三段提交 (3PC)
分布式事务 之 三段提交 (3PC)
1、简介
前面我们说了分布式事务的2PC模型,由于2PC阶段提交模型存在单点故障,事务阻塞等问题,所以就引出了3PC模型,3PC和2PC 很像,不过在3PC的基础上它加入一个预提交阶段,并引入了超时机制。3PC就是三阶段提交,分别为CanCommit
,PreCommit
,DoCommit。
2、CanCommit阶段
CanCommit
阶段Coordinator
协调者会向Participant
参与者发送CanCommit消息,询问它是否可以执行操作,参与者收到消息 后如果他能够执行,那么就会返回给协调者能够执行的命令,我们用Yes
,如果不能,那么就返回不能执行的命令,我们用No
3、PreCommit阶段
PreCommit
阶段如果协调者收到参与者返回的状态值都为Yes
,那么就证明它们都有能力去执行这个操作,那么协调者就会向所有参与者 发送PreCommit
消息,协调者收到PreCommit
消息后,就会执行本地事务,执行成功后将本地事务日志保存到undo_log
和redo_log
中,然后给协调者返回Yes
,如果参与者执行本地事务失败,那么就返回给协调者No
,协调者只要收到一个No
消息,就会给所有参与者发送 中断事务abort
消息,参与者收到abort
消息会对事务就行回滚,因为第二阶段参与者与协调者都引入了超时机制,所以如果参与者没有收到 协调者的PreCommit
消息,或者协调者没有收到参与者返回的预执行结果状态,那么在超过等待时间后,事务就会中断,这就避免了事务的阻塞。
4、DoCommit阶段
协调者收到所有参与者返回的状态都是Yes
,这时协调者就会向所有的参与者都发送DoCommit
,参与者收到DoCommit
后,就会真正地提交事务, 当事务提交成功后,就会返回给协调者Yes
状态,表明我已经完成事务的提交,协调者收到所有的参与者都返回Yes
,那么就完成本次事务,如果有一个 参与者返回No
状态,那么就代表整个事务都要进行回滚,此时协调者就会向所有参与者都发送abort
事务中断消息,参与者收到abort
消息后,就会 进行事务的回滚。
在DoCommit
阶段如果参与者因为超时或者其他原因没有收到协调者发送的DoCommit
消息,那么它也会去提交事务,因为其实在PreCommit
阶段, 从某种意义上来说事务已经是成功了的,所以参与者会认为提交事务成功的可能性很大,所以依然会提交,那我们也可以说,只要PreCommit
阶段所有参与者 都返回了Yes
状态,那么只要进入第三阶段,事务基本上都能执行成功的。
5、总结
对于3PC我们就说完了,3PC是2PC的升级版,它引入了超时机制,解决了单点故障引起的事务阻塞问题,但是3PC依然不能解决事务一致性问题,因为在DoCommit
阶段,如果由于网络或者超时等原因导致参与者接收不到协调者发送过来的abort
中断事务消息,那么过了超时时间,参与者会提交事务,本来应该是进行事务回滚的, 现在好了,提交事务了,那就就出现了数据不一致问题。