三阶段提交(Three-phase Commit)
由于二阶段提交存在着诸如同步阻塞、单点问题、数据不一致等缺陷。所以,研究者们在二阶段提交的基础上做了改进,提出了三阶段提交。
三阶段提交(Three-phase commit,3PL),也叫三阶段提交协议(Three-phase commit protocol),是二阶段提交(2PC)的改进版本。
与两阶段提交不同的是,三阶段提交有两个改动点:
- 引入超时机制 - 同时在协调者和参与者中都引入超时机制。这保证了参与者的事务锁在指定时间后会被自动释放(release),从而避免了因锁长期被占用导致查询性能下降的情况
- 把两阶段提交协议的第一个阶段拆分成了两个独立的节点(CanCommit 和 PreCommit),以保证在最后提交阶段之前,各参与节点的状态是一致的。
所谓的三个阶段分别是:询问,锁定资源,真正提交。
- 第一阶段:CanCommit
- 第二阶段:PreCommit
- 第三阶段:DoCommit
三阶段提交的过程
阶段一:CanCommit
事务询问
3PC 的 CanCommit 阶段其实和 2PC 的准备阶段(Prepare Phase)很像,即协调者向参与者发送 commit
请求,以询问是否可以执行事务提交操作。
但与 2PC 中的准备阶段存在区别的是, 3PC 的 CanCommit 阶段并不真正 commit。
响应反馈
参与者接到 CanCommit
请求之后,正常情况下,如果其自身认为可以顺利执行事务,则返回 Yes 响应,并进入预备状态;否则反馈 No。
阶段二:PreCommit
协调者在得到所有参与者的响应之后,会根据其响应结果执行下面任一一种操作:
- 执行事务预提交
- 中断事务。
情况 1 执行事务预提交
a. 协调者发送预提交请求
协调者向所有参与者节点发出 preCommit
的请求,并进入 prepared
状态。
b. 参与者事务预提交
参与者受到 preCommit
请求后,会执行事务操作,对应 2PC 准备阶段中的 “执行事务”,也会 Undo 和 Redo 信息记录到本地的事务日志中。
c. 各参与者响应反馈
如果参与者成功执行了事务,就反馈 ACK 响应,同时等待指令:提交(commit) 或终止(abort)。
情况 2 中断事务
a. 协调者发送中断请求
协调者向所有参与者节点发出 abort 请求 。
b. 参与者中断事务
参与者如果收到 abort 请求或者超时了,都会中断事务。
阶段三:DoCommit
该阶段进行真正的(参与者本地)事务提交,具体分为以下两种情况:
- 执行提交
- 中断事务
情况 1 执行提交
a. 协调者发送提交请求
协调者在接收到各参与者发送的 ACK 响应后,他将从预提交状态(PreCommit)进入到提交状态(DoCommit)。并向所有参与者发送 doCommit
请求。
b. 参与者事务提交
参与者接收到 doCommit
请求之后,执行正式的本地事务提交。并在完成事务提交之后释放所有事务资源。
c. 参与者响应反馈
参与者的本地事务提交完之后, 参与者向协调者发送 ACK 响应。
d. 完成事务
协调者接收到所有参与者的 ACK 响应之后,完成事务。
情况 2 中断事务
如果协调者没有接收到参与者发送的 ACK 响应(可能是接受者发送的不是 ACK 响应,也可能响应超时),那么就会执行中断事务。
a. 协调者发送中断请求
协调者向所有参与者发送 rollback
请求。
b. 参与者事务回滚
参与者接收到 rollback
请求之后,利用其在 PreCommit
阶段记录的 undo 信息来执行事务的回滚操作,并在完成回滚之后释放所有的事务资源。
c. 参与者反馈结果
参与者完成事务回滚之后,向协调者发送 ACK
消息。
d. 协调者中断事务
协调者接收到参与者反馈的 ACK
消息之后,完成事务的中断。
3.1. 三阶段提交的优点
相对于二阶段提交,三阶段提交主要解决的单点故障问题,并减少了阻塞的时间。
因为一旦参与者无法及时收到来自协调者的信息,他会默认执行 commit。而不会一直持有事务资源并处于阻塞状态。
但是这种机制也会导致数据一致性问题,因为,由于网络原因,协调者发送的 abort 响应没有及时被参与者接收到,那么参与者在等待超时之后执行了 commit 操作。这样就和其他接到 abort 命令并执行回滚的参与者之间存在数据不一致的情况。
三阶段提交的缺点
三阶段提交也会导致数据一致性问题。由于网络原因,协调者发送的 abort 响应没有及时被参与者接收到,那么参与者在等待超时之后执行了 commit 操作。
这样就和其他接到 abort 命令并执行回滚的参与者之间存在数据不一致的情况。
Reference
- 分布式理论 (三) - 2PC 协议 - https://juejin.im/post/5b2664446fb9a00e4a53136e
- 关于分布式事务、两阶段提交协议、三阶提交协议 - http://www.hollischuang.com/archives/681
- 理解分布式事务的两阶段提交 2pc - http://xiaorui.cc/2016/02/25/%E7%90%86%E8%A7%A3%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1%E7%9A%84%E4%B8%A4%E9%98%B6%E6%AE%B5%E6%8F%90%E4%BA%A42pc/
- 如何用消息系统避免分布式事务? - http://blog.jobbole.com/89140/
- Wikipedia Two-phase commit protocol - https://en.wikipedia.org/wiki/Two-phase_commit_protocol
- 分布式事务:两阶段提交与三阶段提交 - https://my.oschina.net/wangzhenchao/blog/736909
- Wikipedia Three-phase commit protocol - https://en.wikipedia.org/wiki/Three-phase_commit_protocol
- 深入理解分布式系统的 2PC 和 3PC - https://www.hollischuang.com/archives/1580
- 2PC 和 3PC 一点理解 - http://jianbeike.blogspot.com/2016/04/2pc3pc.html
- 再谈 2PC 和 3PC - https://yq.aliyun.com/articles/5854
- 对分布式事务及两阶段提交、三阶段提交的理解 - https://www.cnblogs.com/binyue/p/3678390.html