关于分布式事务框架

常用分布式事务框架及其实现原理

分布式事务是微服务架构中的核心难题,主流框架基本围绕 CAP 定理BASE 理论 来做trade-off。


一、分布式事务理论基础

理论 核心思想
2PC(两阶段提交) 协调者先询问所有参与者能否提交(Prepare),全部OK再真正提交(Commit)
TCC(Try-Confirm-Cancel) 业务层面的两阶段提交,Try预留资源,Confirm确认,Cancel回滚
SAGA 将长事务拆成多个本地事务,每个本地事务有对应的补偿操作,正向执行失败则反向补偿
本地消息表 将消息与业务数据在同一事务中写入本地表,异步投递消息保证最终一致性
事务消息 利用MQ的半消息机制,确保本地事务与消息发送的原子性

二、主流框架详解

1. Seata(阿里)

GitHub Star 最多的分布式事务框架,支持四种事务模式:

1.1 AT 模式(自动补偿,最常用)

原理:对业务无侵入,基于 两阶段提交 + 全局锁 实现。

第一阶段(分支事务执行):
  1. 拦截 SQL,解析语义
  2. 查询修改前数据,生成 before-image(前镜像)
  3. 执行业务 SQL
  4. 查询修改后数据,生成 after-image(后镜像)
  5. 生成 undo_log 并与业务 SQL 在同一个本地事务中提交
  6. 向 TC 注册分支事务,申请该行数据的全局锁

第二阶段(全局提交/回滚):
  - 提交:异步清理 undo_log(因为一阶段已提交)
  - 回滚:根据 undo_log 的 before-image 反向补偿,同时校验 after-image 防脏写

关键设计

  • 全局锁:一阶段本地事务提交后,会持有全局锁直到全局事务结束,防止脏写
  • 写隔离:全局事务在本地事务提交前获取全局锁,拿不到则重试或回滚
  • 读隔离:默认不加全局锁(读未提交),可配置 SELECT FOR UPDATE 实现读已提交

适用场景:一般的 CRUD 业务,对业务代码无侵入(仅加 @GlobalTransactional 注解)

1.2 TCC 模式

原理:业务层面的两阶段提交,需要手动编写 Try/Confirm/Cancel 三个方法。

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

关键设计

  • 空回滚:Try 未执行但收到了 Cancel 请求,需要在 Cancel 中判断并直接返回成功
  • 幂等控制:Confirm/Cancel 可能被重复调用,必须保证幂等
  • 悬挂:Cancel 先于 Try 到达,需要阻止 Try 执行(通过记录 Cancel 已执行的状态)

适用场景:非关系型数据库、性能要求高、需要精细控制资源预留的场景

1.3 SAGA 模式

原理:长事务解决方案,每个参与者只需提供正向和反向补偿两个动作。

正向执行:T1 → T2 → T3 → ... → Tn
反向补偿:Tn失败 → C3 → C2 → C1

关键设计

  • 向前恢复:重试失败步骤(适合必须成功的场景)
  • 向后恢复:补偿已完成的步骤(适合可接受失败的场景)
  • 缺乏隔离性:SAGA 模式没有全局锁,可能存在脏写,需要业务层面处理

适用场景:业务流程长、参与者多、对性能要求高、允许最终一致性的场景

1.4 XA 模式

原理:基于数据库的 XA 协议实现两阶段提交,Seata 做了代理优化。

第一阶段:所有参与者执行 SQL 但不提交(XA PREPARE)
第二阶段:TC 通知所有参与者提交或回滚(XA COMMIT/ROLLBACK)

关键设计

  • 数据库层面保证一致性,隔离性好
  • 但全局锁持有时间长,性能较差
  • Seata 的 XA 模式通过代理数据源,对业务无侵入

适用场景:对一致性要求极高,可接受性能损失的场景


2. Hmily(金融级TCC)

百度开源的 TCC 分布式事务框架,后由作者独立维护。

实现原理

核心架构:
  1. Try 阶段:执行业务方法,记录事务日志
  2. Confirm/Cancel 阶段:根据事务日志异步调度执行
  3. 事务恢复:定时任务扫描未完成事务进行重试

关键特性:
  - 异步 Confirm/Cancel:Try 成功后立即返回,Confirm/Cancel 由框架异步执行
  - 事务日志:记录在本地数据库(MySQL/MongoDB/Redis 等)
  - 支持嵌套事务
  - 支持事务上下文传递(RPC 隐式传参)

适用场景:金融业务,对 TCC 模式有深度需求的场景


3. EasyTransaction(易物联)

一个综合性的分布式事务框架,同时支持多种模式。

实现原理

  • TCC:与 Hmily 类似
  • 补偿:SAGA 风格的补偿模式
  • 可靠消息:本地消息表模式
  • 框架会根据调用链路自动选择最优模式

适用场景:需要灵活组合多种事务模式的复杂业务


4. Myth(可靠消息最终一致性)

专注于 本地消息表 模式的分布式事务框架。

实现原理

1. 业务操作与消息记录在同一本地事务中提交
2. 后台线程定时扫描消息表,将未发送的消息投递到 MQ
3. 消费者消费消息并执行本地事务
4. 消费成功后发送确认,框架删除或标记消息已处理
5. 超时未确认的消息会重复投递,消费者需保证幂等

适用场景:异步场景、对实时性要求不高、追求最终一致性


5. RocketMQ 事务消息

RocketMQ 自身提供的分布式事务能力,4.3.0+ 版本支持。

实现原理

1. 生产者发送半消息(Half Message)到 Broker
   → 半消息对消费者不可见
2. Broker 返回发送成功,生产者执行本地事务
3. 根据本地事务结果,发送 Commit 或 Rollback 给 Broker
   → Commit:半消息变为可消费消息
   → Rollback:半消息被删除
4. 如果 Broker 长时间未收到二次确认(网络闪断等):
   → 启动回查机制,检查本地事务状态
   → 根据回查结果决定 Commit 或 Rollback
5. 消费者消费消息,执行远程事务
   → 消费失败会重试,消费者需保证幂等

适用场景:异步解耦场景、与 RocketMQ 生态紧密集成的系统


6. XA 协议(数据库原生方案)

所有支持 XA 协议的数据库自带的分布式事务能力。

实现原理

全局事务管理器(TM)协调:
  1. TM 通知所有 RM(资源管理器)开启 XA 事务
  2. 各 RM 执行 SQL,但不提交(XA PREPARE)
  3. 所有 RM Prepare 成功后,TM 发送 XA COMMIT
  4. 任一 RM Prepare 失败,TM 发送 XA ROLLBACK

局限:
  - 全局锁持有时间长,吞吐量低
  - 对数据库有强依赖
  - 单点故障风险(TM)
  - 有 XA 2PC 的固有问题:协调者宕机可能导致参与者长时间阻塞

适用场景:传统数据库架构、强一致性需求、可接受性能损失


三、框架对比总结

框架 支持模式 侵入性 性能 一致性 维护状态
Seata AT/TCC/SAGA/XA AT低/TCC高 AT较好 AT强一致 活跃(阿里)
Hmily TCC 强一致 社区维护
EasyTransaction TCC/补偿/可靠消息 较好 最终一致 社区维护
Myth 本地消息表 最终一致 社区维护
RocketMQ 事务消息 最终一致 活跃(阿里)
XA 协议 两阶段提交 强一致 数据库原生

四、如何选型

1. 强一致性 + 低侵入 → Seata AT 模式(最推荐)
2. 强一致性 + 高性能 → Seata TCC 模式 / Hmily
3. 最终一致性 + 异步解耦 → RocketMQ 事务消息
4. 长流程 + 最终一致性 → Seata SAGA 模式
5. 传统架构 + 强一致性 → XA 协议
6. 综合场景 → Seata(多种模式可混用)

实际生产环境中,Seata 是目前使用最广泛的方案,其 AT 模式对业务侵入最小、接入最简单,而 TCC/SAGA 可覆盖更复杂的场景。RocketMQ 事务消息则在异步场景中表现出色。

posted @ 2026-05-14 15:38  webzd  阅读(3)  评论(0)    收藏  举报