先看看 数据库系统中的本地事务逻辑 InnoDB的事务 和 分布式系统数据同步的CAP问题 从 CAP 到 BASE

TCC

TCC : Try - Confirm - Cancel 基于补偿的分布式事务解决方案

  • Try: 参与者本地提交结果,保存在本地
  • Confirm:参与者确认本地结果完成,所有的参与者都完成后,则表示 提交结束
  • Cancel:如果存在一个参与者没有完成,则所有的参与者都cancel

2PC

2PC 可以认为是一个强一致性的方案

2PC:基于协调者的分布式事务解决方案。分为 prepare commit rollback 三个模式

  • 准备提交:判断参与者是不是可以提交 , 这个时候事务信息已经发送到参与者了
  • 提交:直接提交

如果任意一个参与者没有提交成功,则全部回滚。

存在的问题:

  • 同步阻塞: 提交阶段,每一个参与者都处于阻塞状态,等待其他参与者的响应帮助协调者做最后的判断
  • 单点问题:协调者如果在提交阶段出现问题了,那么其他协调者将永远无法继续完成事务操作
  • 数据不一致:发生网络分区之后,部分节点无法接收到 commit 请求,就会发生数据不一致的情况
  • 过于保守:一个参与者出现问题无法响应,协调者只能通过超时机制来判断是否需要中断

3PC

3PC: 属于 2PC的改进,将准备阶段拆分为 CanComiit 和 PreCommit 阶段

  • CanCommit:询问是不是可以参与事务
  • PreCommit:向可以参与的节点发送预提交的信息 (作用? 让参与者完成提交前的所有准备工作,防止提交失败,避免出现不可预期的情况,保证原子性和一致性; 最多是提高健壮性)
    • 执行事务预提交
    • 中断事务
  • DoCommit: 提交阶段 - 存在超时机制或者心跳检测机制,如果协调者超时未收到参与者的响应,则尝试回退或者重新提交
    • 执行提交
    • 中断事务

在3PC中,一旦进入阶段三,如果协调者出现问题或者协调者和参与者出现网络分区,参与者可能会无法获取到协调者的doCommit 请求,这个时候参与者在等待超时后,可以选择继续事务提交。

基于上述,相比于2PC ,3PC降低了参与者的阻塞范围,处理了单点问题、doCommit阶段的数据不一致问题。

但是因为引入了一个 CanCommit 阶段,在这个时候如果发生了网络分区,还是会出现 canCommit 阶段的数据不一致的问题

总结一下:

TCC适合存在补偿机制的场景下工作,3PC适合在高并发、高可用场景下操作;