分布式事务解决方案¶
一、为什么需要分布式事务¶
一个操作跨多个服务 / 数据库:
- 下单:订单库、库存库、账户库。
- 跨服务调用失败,前面的成功了,后面的失败了。
二、理论模型¶
1. 2PC(两阶段提交)¶
- 准备阶段:所有参与者预执行,锁资源,告诉协调者"可以"。
- 提交阶段:所有都 OK,协调者发 commit;任一失败,发 rollback。
缺点: - 同步阻塞,锁资源时间长。 - 协调者单点。 - 网络分区时不确定。
2. 3PC¶
加了 CanCheck 阶段和超时机制,减少阻塞,但仍复杂。
3. TCC(Try-Confirm-Cancel)¶
- Try:预留资源(冻结库存、冻结金额)。
- Confirm:确认执行。
- Cancel:取消释放。
业务侵入大,但性能好,适合资金类。
4. Saga¶
长事务拆成多个本地事务,每个有对应补偿动作。失败时反向补偿。适合长流程、跨多服务。
5. 本地消息表(最终一致)¶
把"发消息"和"本地业务"放在同一个本地事务:
后台任务扫 message 表,发 MQ,消费者处理。成功后更新 message 状态。
优点:简单、可靠。缺点:有延迟。
6. 事务消息(RocketMQ)¶
RocketMQ half message + 回查:
- 生产者发 half 消息(消费者看不到)。
- 执行本地事务。
- 根据本地事务结果 commit / rollback 消息。
- 如果长时间没确认,MQ 回查本地事务状态。
三、选型¶
| 方案 | 一致性 | 性能 | 业务侵入 | 适用 |
|---|---|---|---|---|
| 2PC / XA | 强一致 | 低 | 无 | 传统 DB 跨库 |
| TCC | 最终一致 | 高 | 大 | 资金、账户 |
| Saga | 最终一致 | 高 | 中 | 长流程 |
| 本地消息表 | 最终一致 | 高 | 小 | 大多数业务 |
| 事务消息 | 最终一致 | 高 | 小 | RocketMQ 环境 |
四、Seata¶
阿里开源的分布式事务框架,支持 AT、TCC、Saga、XA 模式:
- AT 模式:对业务无侵入,自动生成反向 SQL 回滚。
- TCC:手写 Try/Confirm/Cancel。
面试加分
- 真正强一致的分布式事务性能都差,互联网公司大多用最终一致。
- 本地消息表是最实用的方案。
- TCC 的空回滚、悬挂问题:Try 没到先收到 Cancel,要记录事务状态防止空回滚。