二阶段提交(2PC)方案
二阶段提交(Two-phase Commit,2PC),需要引入协调者 Coordinator 来参与事务行为,并且最终决定是否提交事务。
二阶段提交分为两个阶段:
- 提交事务阶段
- 协调者询问每个系统是否可以执行提交事务的操作
- 每个系统执行本地事务,并写入本地的 Undo/Redo 日志,此时事务还没有提交。
- 返回 yes/no 给协调者。
- 执行事务阶段
- 协调者收到每个系统返回的执行结果,如果全部是 yes,则通知每个系统去提交事务。
- 如果其中有一个 No,则通知返回 yes 的系统去回滚事务。
存在的问题:
- 同步阻塞。二阶段提交的过程当中,所有参与事务操作的节点都处于同步阻塞状态,无法进行其它操作。
- 单点问题。如果在第二阶段,协调者发生障碍,所有的参与者都处于锁定事务资源的状态,从而无法继续完成事务操作。
TCC 补偿事务方案
TCC 补偿事务英文名是 Try-Confirm-Cancel,即这三个阶段。
Try:尝试从业务系统获取预留资源,保证预留资源的隔离性。
Confirm:通知业务系统执行业务。默认一定成功,如果失败需要有重试操作。
Cancel:如果 Confirm 阶段有业务系统执行失败,则通知所有的业务系统释放预留资源或回滚事务。
可靠消息最终一致性方案
基于可靠消息最终一致性方案有两种主流的实现方式。
本地消息表
本地消息表方案是一种很巧妙的分布式解决方案,它将业务数据和消息置于同一个事务中操作,最终将消息通知到其它系统,实现最终一致性。
RocketMQ
RocketMQ 本身支持事务消息。执行流程如下。
- A 系统在执行本地事务之前发送一个半事务消息到 RocketMQ 中。
- RocketMQ 发送一个 ack 回执状态给 A。
- A 收到半事务消息投递成功的回执,则去执行本地事务。
- A 根据本地事务执行状态向 RocketMQ 发送 commit 或者 rollback 执行。
- 如果 RocketMQ 收到 commit 执行,则将本地的半事务消息投递到 B 系统。如果是收到 rollback 指令,则删除本地表中的半事务消息。