分布式事务一致性之三阶段提交

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

  1. 同时在协调者和参与者引入超时机制
  2. 在第一阶段和第二阶段插入一个准备阶段,目的是保证最后提交之前参与节点的状态都是一致的

三阶段提交有cancommit,precommit,docommit三个阶段

CanCommit阶段

  1. 事务询问阶段:协调者向参与者发送commit请求,等待参与者响应
  2. 响应反馈:参与者接到CanCommit请求后,正常情况下,如果其自身认为可以顺利执行事务就返回Yes并进入预备状态,否则返回NO

PreCommit阶段

协调者根据参与者的反应情况来决定是否继续事务的PreCommit操作

1.如果协调者收到的所有参与者的反馈都是Yes响应,那么就会执行事务的预执行

  1. 发送预提交请求:协调者向参与者发送PreCommit请求并且进入Prepared阶段
  2. 事务预提交:参与者接收到PreCommit请求后会执行事务操作,并将undo和redo信息记录到事务日志中
  3. 响应反馈:如果参与者成功执行了事务操作则返回ACK响应并开始等待最终指令

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

  1. 向所有协调者发送中断请求
  2. 中断事务:参与者收到来自协调者的中断请求后,执行事务中断

docommit阶段

该阶段仍然存在两种情况

1.参与者收到收到协调者提交的命令

  1. 协调者收到所有参与者提交的请求,那么协调者和参与者进入提交状态,协调者向所有参与者发送docommit请求
  2. 事务提交 参与者接受到doCommit请求后,执行任务的提交,并在成功提交之后释放所有的事务资源
  3. 向协调者发送事务真正提交相应
  4. 协调者收到提交完成响应后完成事务

2.协调者没有收到参与者发送的ACK响应,那么会中断事务

  1. 协调者向所有参与者发送中断请求
  2. 参与者利用回滚日志回滚
  3. 参与者完成事务回滚后,向协调者发送ACK消息
  4. 协调者收到ACK消息后执行事务的中断

在doCommit阶段,如果参与者无法及时收到来自协调者的命令,在超时之后,会继续进行事务提交,因为从概率上讲此阶段其它节点提交事务的概率很大

例子

举例来说,假设有一个决策小组由一个主持人负责与多位组员以电话联络方式协调是否通过一个提案,以两阶段提交来说,主持人收到一个提案请求,打电话跟每个组员询问是否通过并统计回复,然后将最后决定打电话通知各组员。
要是主持人在跟第一位组员通完电话后失忆,而第一位组员在得知结果并执行后老人痴呆,那么即使重新选出主持人,也没人知道最后的提案决定是什么,也许是通过,也许是驳回,不管大家选择哪一种决定,都有可能与第一位组员已执行过的真实决定不一致,老板就会不开心认为决策小组沟通有问题而解雇。
三阶段提交即是引入了另一个步骤,主持人打电话跟组员通知请准备通过提案,以避免没人知道真实决定而造成决定不一致的失业危机。
为什么能够解决二阶段提交的问题呢?
回到刚刚提到的状况,在主持人通知完第一位组员请准备通过后两人意外失忆,即使没人知道全体在第一阶段的决定为何,全体决策组员仍可以重新协调过程或直接否决,不会有不一致决定而失业。
那么当主持人通知完全体组员请准备通过并得到大家的再次确定后进入第三阶段,
当主持人通知第一位组员请通过提案后两人意外失忆,这时候其他组员再重新选出主持人后,
仍可以知道目前至少是处于准备通过提案阶段,表示第一阶段大家都已经决定要通过了,此时便可以直接通过

三阶提交缺陷

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值