易君召
易君召
发布于 2026-09-04 / 38 阅读
0

常用分布式事务实现策略

分布式事务核心目标:跨多个数据库 / 服务的数据要么全部成功,要么全部失败,解决 CAP、BASE 理论下数据一致性问题,分为强一致性、最终一致性两大类。

1. 2PC(两阶段提交)

角色:协调者、多个参与者

  • 阶段 1(准备阶段):协调者通知所有参与者执行事务预提交,不真正提交;参与者执行 SQL,写 undo/redo 日志,返回成功或失败。

  • 阶段 2(提交 / 回滚阶段):

    • 全部准备成功:协调者下发commit,各参与者正式提交事务,释放资源。

    • 任意一个失败:协调者下发rollback,全部回滚。

优点:强一致性,传统数据库原生支持。 缺点:同步阻塞,协调者单点故障;长时间占用数据库锁,性能差。 适用:数据库内部分布式(如 MySQL XA 事务),不适合高并发微服务。

MySQL XA 就是 2PC 实现。

2. 3PC(三阶段提交)

在 2PC 基础上拆分准备阶段,引入预提交,解决 2PC 长时间阻塞问题。

  1. CanCommit:协调者询问参与者是否可以执行事务

  2. PreCommit:预执行,不提交

  3. DoCommit:真正提交 / 回滚

优点:降低阻塞时长,部分解决协调者故障。 缺点:依然有阻塞,网络异常会出现数据不一致;工业落地很少。

2PC/3PC 小结:属于强一致性方案,性能短板明显,微服务很少直接用。

最终一致性方案(微服务主流,BASE)

3. TCC(Try‑Confirm‑Cancel)

业务层手动编码实现,把事务拆分成 3 个接口,每个服务实现这三个方法:

  1. Try:预留资源,做检查、锁定资源,不做真正业务提交。

  2. Confirm:确认执行业务,Try 全部成功后执行;幂等。

  3. Cancel:释放预留资源,任意 Try 失败,全部回滚;幂等。

特点:

  • 完全业务代码实现,不依赖数据库事务;性能较好。

  • 必须保证 Confirm/Cancel 幂等、防悬挂、空回滚。

  • 开发成本高,侵入业务。 框架:Seata‑TCC,ByteTCC 场景:资金、库存扣减等核心业务。

悬挂:Cancel 先于 Try 执行;空回滚:Try 还没执行,先调用 Cancel。

4. SAGA 模式

长事务解决方案,把分布式大事务拆成一串本地小事务。每个本地事务有正向操作 + 补偿回滚操作。 两种实现方式:

  1. 编排式 SAGA(Choreography):服务之间通过消息互相调用,无中心协调器。服务发布事件,其他服务监听事件执行。耦合高,流程散落在各个服务。

  2. 编排式 SAGA(Orchestration):中心协调器,协调器告诉各个服务执行正向 / 补偿动作。流程集中管理,推荐微服务使用。

优点:适合长事务,无锁,性能好;不需要资源预留。 缺点:补偿逻辑复杂;不保证隔离性,中间会出现脏数据。 框架:Seata‑Saga,Apache Camel Saga。 场景:订单流程、长业务流程。

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

核心思想:事务和消息记录在同一个本地数据库事务。

  1. 业务本地事务:执行业务 SQL + 写入一张本地消息表(同一个本地事务)。

  2. 后台定时任务轮询本地消息表,发送消息到 MQ。

  3. 消费端收到消息执行业务;消费失败则重试。

  4. 消费成功后更新消息表状态。

优点:简单可靠,不依赖中间件高级特性。 缺点:依赖本地数据库,轮询有延迟;需要处理消息幂等。

早期阿里开源方案思想。

6. MQ 事务消息(RocketMQ 事务消息)

本质是本地消息表思想下沉到 MQ 中间件层。 流程:

  1. Producer 发送半消息到 MQ,消息对消费者不可见。

  2. Producer 执行本地业务事务。

  3. 根据本地事务结果,向 MQ 提交 commit/rollback。

  4. commit 后消息才对消费者可见;rollback 消息丢弃。

  5. 如果 Producer 宕机,MQ 会回查 Producer 本地事务状态。

优点:不用自己维护本地消息表。 缺点:仅 RocketMQ 原生支持;Kafka 没有事务消息;需要实现事务回查接口;只保证生产者可靠,消费者依旧要幂等重试。

7. AT 模式(Seata AT,最常用)

自动代理 SQL,无业务侵入,国内微服务使用最多。

AT 是改良版 2PC,基于 undo_log 回滚日志。

  1. 一阶段:执行业务 SQL,Seata 拦截,保存数据快照到undo_log表;业务直接提交本地事务,释放锁。

  2. 二阶段‑commit:删除 undo_log 即可。

  3. 二阶段‑rollback:读取 undo_log 快照,生成补偿 SQL 回滚数据。

优点:零业务侵入,开发简单。 缺点:需要数据库支持;会写 undo_log;没有隔离性,会出现脏读;全局锁性能瓶颈。 注意:AT 是最终一致性,不是强一致。

方案对比总结表

方案

一致性

侵入业务

性能

适用场景

2PC(XA)

强一致

低

差

数据库内部,短事务

TCC

最终一致

高

较好

资金、库存核心业务

SAGA

最终一致

中

好

长事务业务流程

Seata AT

最终一致

极低

中等

普通微服务业务(最常用)

本地消息表

最终一致

中

好

异步通知场景

RocketMQ 事务消息

最终一致

中

好

异步 MQ 解耦场景

选型经验

  1. 普通微服务业务优先 Seata AT,开发成本最低。

  2. 涉及资金扣减、资源锁定,优先 TCC。

  3. 长链路、长耗时业务流程,选 SAGA 编排。

  4. 异步解耦场景:本地消息表 / RocketMQ 事务消息。

  5. 高并发场景尽量避开 XA‑2PC。

额外补充问题

分布式事务绕不开三个问题:幂等性、空回滚、悬挂、防脏读,无论哪种最终一致性方案都要处理。


本文原创作者:易君召,详见:https://www.yijunzhao.cn/authors/yijunzhao,转载请注明出处。

原文链接 https://www.yijunzhao.cn/archives/common-distributed-transaction-implementation-strategies-guide

欢迎访问 小易撩挨踢

https://www.yijunzhao.cn/