先做分类梳理:
- 强一致刚性事务:XA(2PC,数据库底层两阶段)
- 柔性最终一致
- 基于数据库自动补偿:Seata AT(最常用,无侵入)
- 业务手动预留补偿:TCC(Try-Confirm-Cancel)
- 长流程逆向补偿:SAGA(状态机/事件驱动)
- 异步解耦消息方案:可靠消息事务(本地消息表/RocketMQ事务消息、最大努力通知)
- Seata是框架载体,内置XA/AT/TCC/SAGA四种模式,不是独立事务模型。
一、各方案核心原理
1. XA(标准2PC,数据库层面强一致)
- 规范:X/Open XA,TM事务管理器协调多个DB资源管理器RM
- 两阶段:
- Prepare:各DB执行SQL、持有行锁不提交,返回就绪;任一失败全部回滚
- Commit/Rollback:全部就绪则统一提交,否则全部回滚
- 一致性:强一致、完整ACID,中间无脏数据
- 底层依赖:数据库原生XA驱动(MySQL、Oracle支持)
2. 基于消息的最终一致性(异步柔性)
分为两类:
(1)可靠消息事务(核心业务)
- 两种实现:
- 本地消息表:业务库新建msg表,业务操作+写入消息在同一本地事务,定时任务轮询发MQ;消费失败重试,消费成功标记消息完成
- RocketMQ事务消息:半消息+本地事务回调,MQ内置状态存储,无需自建消息表
- 核心:本地事务原子绑定消息发送,保证业务成功则消息必投;消费端幂等防重复
(2)最大努力通知(弱一致,非核心)
本地事务完成后循环重试推送通知,超过阈值人工兜底;无原子绑定,允许消息丢失,仅用于短信、回调通知。
3. 基于数据库的一致性:Seata AT(自动补偿,业务无侵入)
- 一阶段:执行业务SQL,同步记录undo回滚日志,本地事务直接提交释放锁;全局锁标记行隔离脏写
- 二阶段Commit:异步删除undo日志,快速结束
- 二阶段Rollback:读取undo日志自动生成补偿SQL回滚数据
- 本质:框架自动实现补偿事务,仅依赖关系型数据库,注解
@GlobalTransactional即用
4. TCC(应用层三阶段手动补偿)
三段接口全部业务手动编码:
- Try:校验参数、冻结/预留资源(冻结库存、锁定余额),提交本地事务释放DB锁
- Confirm:全局成功,确认扣减预留资源(仅使用Try冻结数据)
- Cancel:全局失败,释放冻结资源
- 特点:无全局长锁,支持Redis/Mongo等非DB资源,一致性感知最强的柔性方案
5. SAGA(长事务逆向补偿)
将长业务拆分为N个独立本地事务,每个正向操作对应反向补偿操作:
- 正向:T1→T2→T3依次提交本地事务(无资源锁定)
- 失败补偿:若T3失败,逆序执行C3→C2→C1撤销已完成操作 两种实现:
- 编排式(Seata SAGA状态机):中心调度器定义流程、补偿逻辑
- 编排式(事件驱动):服务间通过MQ消息联动,无中心协调
- 适用跨系统、长周期流程(下单→出库→物流→结算)
6. Seata说明
Apache Seata是分布式事务框架,统一TC事务协调器,同时封装4种模式:XA / AT / TCC / SAGA,一套框架切换不同一致性方案。
二、六大方案核心维度对比总表
| 对比维度 | XA(2PC) | Seata AT(数据库自动补偿) | TCC | SAGA | 可靠消息事务(MQ) | 最大努力通知 |
|---|---|---|---|---|---|---|
| 一致性等级 | 强一致(ACID) | 最终一致 | 准强最终一致(Try锁定) | 最终一致 | 最终一致 | 弱最终一致 |
| 锁机制 | 全局长锁,Prepare阶段持续阻塞 | 一阶段释放DB锁,全局行锁防脏写 | Try阶段冻结业务资源,无DB长锁 | 无任何锁,允许脏读 | 无锁,完全异步 | 无锁 |
| 性能并发 | 极差,高并发阻塞 | 中等,比XA强很多 | 最优,高吞吐 | 高吞吐,适合长流程 | 极高,异步解耦 | 极高 |
| 代码侵入 | 极低,仅配置XA数据源 | 极低,仅注解@GlobalTransactional | 极高,每个服务写3套接口 | 中高,每个步骤写正向+补偿 | 中,建消息表/适配事务MQ | 低,定时重试任务 |
| 数据库依赖 | 必须支持XA协议 | 仅支持关系型DB(MySQL/Oracle) | 无依赖,支持Redis/Mongo/第三方接口 | 无依赖,任意存储/外部系统 | 依赖MQ+关系库 | MQ即可 |
| 隔离性 | 完美隔离,无脏读脏写 | 存在脏写风险(全局锁规避) | 业务层隔离,无脏数据 | 最差,大量中间脏数据可见 | 中间态长期可见 | 中间态长期可见 |
| 开发成本 | 低,配置即用 | 极低,业务零改造 | 极高,幂等/空回滚/悬挂全手动处理 | 中高,维护状态机+补偿逻辑 | 中等,幂等、消息重试、死信 | 最低,仅重试推送 |
| 故障风险 | 协调者宕机导致锁阻塞死锁 | undo日志丢失会数据不一致 | 业务编码错误易资损 | 补偿逻辑出错不可逆 | MQ宕机丢失消息,消费重复 | 消息丢失必须人工兜底 |
| 典型场景 | 银行核心转账、低并发金融账务 | 普通微服务电商订单、库存、积分 | 高并发支付、库存扣减、Redis事务 | 长流程:旅游预订、物流、跨企业审批 | 订单发券、充值、异步库存扣减 | 短信通知、支付回调、营销推送 |
三、优缺点深度拆解
1. XA(2PC)
优点
- 数据库原生支持,应用零改造,标准ACID强一致
- 无需业务写补偿逻辑,回滚完全自动 缺点
- Prepare阶段长时间持有行锁,并发一高直接大量阻塞,性能灾难
- 协调器TC宕机时,分支资源永久锁定,人工解锁成本高
- 分库分表场景锁范围放大,死锁概率飙升 局限:只适合并发量小、资金绝对严谨的传统金融核心系统,互联网高并发业务基本淘汰。
2. Seata AT(最主流互联网方案)
优点
- 无业务侵入,原有CRUD代码无需改动,接入成本极低
- 一阶段释放DB锁,性能远超XA,适配绝大多数电商业务
- Seata框架成熟,undo日志、全局锁、重试内置封装 缺点
- 仅支持关系型数据库,无法对接Redis、第三方外部接口
- 存在脏写问题(一阶段提交后其他事务可更新未回滚数据),需通过业务唯一索引/全局锁规避
- 回滚依赖undo日志,日志损坏会造成数据不一致
3. TCC(高性能核心交易首选)
优点
- 性能天花板:一阶段立刻释放数据库锁,无全局阻塞
- 不绑定数据库,支持缓存、第三方支付、外部API参与分布式事务
- Try资源冻结,业务层几乎不会出现中间脏数据,一致性可控 缺点
- 侵入极强:每个分布式接口必须实现Try/Confirm/Cancel三套代码,代码量翻倍
- 复杂边界问题全部手动处理:空回滚、业务悬挂、幂等、防重复Confirm/Cancel,极易出资损bug
- 表结构常需改造(增加冻结字段、冻结库存数量)
4. SAGA(长流程、跨系统专用)
优点
- 全程无锁,吞吐量最高,支持数小时/天级长事务
- 兼容遗留系统、外部第三方服务(对方不提供TCC三接口)
- 编排式状态机可视化流程,复杂业务流程易维护 缺点
- 无隔离性,流程中途其他服务可读取到未完成脏数据
- 不可逆业务(扣款、发货)补偿逻辑极难实现,补偿失败无法兜底
- 流程越长,补偿链路越复杂,维护成本高
5. 可靠消息事务(异步解耦场景)
优点
- 完全异步,主流程不阻塞,吞吐最高,削峰填谷
- 服务高度解耦,订单、库存、积分可独立扩容迭代
- 实现简单,本地消息表无框架依赖,轻量落地 缺点
- 一致性延迟,中间态对用户可见,不能用于同步强一致业务
- 必须处理重复消费、消息丢失、死信队列、定时校对
- 主业务与消息表耦合,多业务需多张消息表
6. 最大努力通知(边缘通知场景)
优点:实现最简单,无需本地事务绑定消息 缺点:一致性最弱,存在消息永久丢失风险,核心资金业务严禁使用,仅做通知类弱同步。
四、选型决策指南(业务场景直接对照)
- 低并发、资金强一致、不能容忍中间脏数据 → XA(传统银行内网账务)
- 普通微服务、MySQL为主、不想改业务代码、中等并发 → Seata AT(90%互联网电商、后台管理系统)
- 高并发核心交易、Redis/第三方支付参与、追求极致性能 → TCC(秒杀库存、支付清算、账户余额)
- 超长业务流程、跨外部公司/遗留系统、步骤多周期长 → SAGA(酒店预订、物流履约、供应链审批)
- 主流程同步、下游可异步延迟执行、服务解耦 → 可靠消息事务(下单发优惠券、充值到账、异步统计)
- 仅做通知推送、允许短暂不一致、失败人工处理 → 最大努力通知(短信、营销推送、支付结果回调)
五、易混淆概念澄清
- Seata ≠ 独立事务方案 Seata是框架,AT/TCC/SAGA/XA是它提供的四种事务模式,选型先选模型,再用Seata落地。
- AT与XA都基于数据库,但底层逻辑完全不同 XA是数据库原生两阶段锁;AT是框架拦截SQL生成undo日志,一阶段直接提交本地事务,无长锁。
- TCC与SAGA补偿逻辑区别
- TCC:事前预留冻结资源,Confirm才真正扣减,无脏数据;
- SAGA:事前直接提交修改,失败再逆向撤销,全程可见脏数据。
- 可靠消息是异步柔性,XA/AT/TCC/SAGA默认同步执行 消息事务会将分布式事务拆成两段本地事务异步执行,其余方案整体同步阻塞。
注意:本文归作者所有,未经作者允许,不得转载