跳转至

分布式事务解决方案

一、为什么需要分布式事务

一个操作跨多个服务 / 数据库:

  • 下单:订单库、库存库、账户库。
  • 跨服务调用失败,前面的成功了,后面的失败了。

二、理论模型

1. 2PC(两阶段提交)

  • 准备阶段:所有参与者预执行,锁资源,告诉协调者"可以"。
  • 提交阶段:所有都 OK,协调者发 commit;任一失败,发 rollback。

缺点: - 同步阻塞,锁资源时间长。 - 协调者单点。 - 网络分区时不确定。

2. 3PC

加了 CanCheck 阶段和超时机制,减少阻塞,但仍复杂。

3. TCC(Try-Confirm-Cancel)

  • Try:预留资源(冻结库存、冻结金额)。
  • Confirm:确认执行。
  • Cancel:取消释放。

业务侵入大,但性能好,适合资金类。

4. Saga

长事务拆成多个本地事务,每个有对应补偿动作。失败时反向补偿。适合长流程、跨多服务。

5. 本地消息表(最终一致)

把"发消息"和"本地业务"放在同一个本地事务:

BEGIN;
INSERT INTO order(...);
INSERT INTO message(biz_id, payload, status);
COMMIT;

后台任务扫 message 表,发 MQ,消费者处理。成功后更新 message 状态。

优点:简单、可靠。缺点:有延迟。

6. 事务消息(RocketMQ)

RocketMQ half message + 回查:

  1. 生产者发 half 消息(消费者看不到)。
  2. 执行本地事务。
  3. 根据本地事务结果 commit / rollback 消息。
  4. 如果长时间没确认,MQ 回查本地事务状态。

三、选型

方案 一致性 性能 业务侵入 适用
2PC / XA 强一致 传统 DB 跨库
TCC 最终一致 资金、账户
Saga 最终一致 长流程
本地消息表 最终一致 大多数业务
事务消息 最终一致 RocketMQ 环境

四、Seata

阿里开源的分布式事务框架,支持 AT、TCC、Saga、XA 模式:

  • AT 模式:对业务无侵入,自动生成反向 SQL 回滚。
  • TCC:手写 Try/Confirm/Cancel。

面试加分

  • 真正强一致的分布式事务性能都差,互联网公司大多用最终一致。
  • 本地消息表是最实用的方案。
  • TCC 的空回滚、悬挂问题:Try 没到先收到 Cancel,要记录事务状态防止空回滚。