两阶段提交2PC,三阶段提交3PC

  为了实现分布式事务,人们提出了分两个阶段提交事务,以及改进版,分三个阶段提交事务。
  为了实现不同事务参与者之间事务的一致性,需要有一个统一的事务管理者,来对这些参与者进行统一的事务管理。
  两阶段提交过程大致如下:

准备阶段

  • 管理者向参与者发起事务请求,询问是否可以执行事务。
  • 参与者执行事务,写undo日志和redo日志,并返回事务执行成功或失败。

提交阶段

  • 管理者接到参与者返回的信息,如果有一个失败,发送rowback消息,所有参与者回滚事务,返回ack响应;如果全部成功,发送commit消息,所有参与者提交事务,返回ack响应。
  • 最终释放参与者在事务中占用的锁资源。

  缺点是:

  1. 同步阻塞: 参与者在整个阶段都是事务阻塞型,当参与者占用公共资源时,其他第三方节点访问公共资源的时候不得不处于阻塞状态。
  2. 单点故障: 如果管理者挂掉了,参与者就会一直处于阻塞状态,尤其是第二阶段,参与者处于锁定事务占用资源的状态。新的管理者也不知道哪些节点执行成功,哪些失败了。
  3. 数据不一致: 管理者发送commit消息后,由于网络等原因,一部分节点收到了消息,执行了commit命令,而一部分没有收到该消息,此时就会出现数据不一致的现象。

  为了应对这些缺点,提出了三阶段提交方案,过程如下:
1. CanCommit

  • 管理者发送CanCommit请求,询问能否提交事务。
  • 参与者接收CanCommit请求,如果认为自己能提交事务,返回yes,并进入预提交状态,否则返回no。

2. PreCommit

  • 管理者发送PreCommit请求。
  • 参与者接收PreCommit请求,执行事务,并将undo,redo信息记录到日志文件中。
  • 如果执行成功就返回ack响应,等待最终的指令。

如果有一个节点返回no响应,或者超时后仍然没有收到ack响应,则开始执行任务中断。

  • 管理者向所有参与者发送absorb请求。
  • 参与者收到absorb请求(或者超时后,仍未收到管理者的请求),执行事务中断。

3. DoCommit

  • 管理者接收到所有参与者的ack响应,从预提交阶段进入到提交阶段,发送DoCommit请求。
  • 参与者接收到DoCommit请求,开始提交事务,释放所有的资源。
  • 成功提交的参与者向管理者发送ack响应。
  • 管理者收到所有参与者的ack响应,完成事务。

如果管理者收到的不是ack响应,或者响应超时,开始执行事务中断。

  • 管理者项目所有参与者发送absorb请求。
  • 参与者收到absorb请求,回滚事务,释放资源。
  • 所有的参与者完成事务回滚,返回ack响应。
  • 管理者接收到所有的参与者ack请求,执行事务中断。

  三阶段提交主要解决了单点故障问题,并减少阻塞。如果在第三阶段参与者长时间不能得到管理者发送的消息,默认执行commit操作。不过这样会导致数据一致性问题,如:网络不好,管理者的absorb请求及时发送过来,而这个节点却执行了commit操作。
  三阶段提交为管理者和参与者都提供了超时机制。

参考资料:
https://www.hollischuang.com/archives/681

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值