先看看 数据库系统中的本地事务逻辑 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适合在高并发、高可用场景下操作;