分布式事务方案:Seata XA、AT、TCC 与 MQ
只要一个业务操作同时写多个服务的数据,就会遇到分布式事务问题。比如下单要写订单、扣库存、扣余额,任意一步失败都可能造成数据不一致。
一句话概括:Seata 通过 TC、TM、RM 协调全局事务和分支事务;XA 追求强一致但性能差,AT 通过 undo log 提升性能,TCC 通过业务代码完成 Try/Confirm/Cancel,MQ 通过异步消息实现最终一致。
Seata 三个角色
| 角色 | 全称 | 作用 |
|---|---|---|
| TC | Transaction Coordinator | 事务协调者,维护全局事务和分支事务状态 |
| TM | Transaction Manager | 事务管理器,定义全局事务范围,发起提交或回滚 |
| RM | Resource Manager | 资源管理器,管理分支事务资源,注册和汇报分支状态 |
可以这样理解:
- TM 是发起人。
- RM 是各个服务里的执行者。
- TC 是总协调者。
XA 模式
XA 是强一致思路,偏 CP。
优点是强一致,缺点是资源锁定周期长,性能较差。适合对一致性要求极高的场景。
AT 模式
AT 也是两阶段模型,但一阶段会直接提交本地事务,并记录undo log。
流程:
- RM 注册分支事务。
- 记录更新前后的数据快照,也就是
undo log。 - 执行业务 SQL 并提交。
- 报告事务状态给 TC。
- 二阶段提交时删除
undo log。 - 二阶段回滚时根据
undo log恢复数据。
AT 相比 XA,资源锁定时间更短,性能更好,适合很多互联网业务。
AT 模式里有两个容易被问深的点:undo log和全局锁。
| 机制 | 作用 |
|---|---|
undo log | 保存修改前后的数据快照,二阶段回滚时用来恢复数据 |
| 全局锁 | 防止多个全局事务同时修改同一行数据,避免回滚时数据被别人改乱 |
AT 回滚大概是这样:
所以 AT 不是“魔法回滚”,它依赖快照、全局锁和数据校验。这个点讲出来,分布式事务的回答会厚很多。
TCC 模式
TCC 需要业务自己实现三个阶段:
| 阶段 | 含义 |
|---|---|
| Try | 检查并预留资源 |
| Confirm | 真正完成资源操作 |
| Cancel | 释放预留资源,是 Try 的反向操作 |
TCC 性能较好,但开发成本高。因为每个业务都要写 Try、Confirm、Cancel,还要处理幂等、空回滚、悬挂等问题。
TCC 里这三个坑尤其要记:
| 问题 | 含义 | 处理思路 |
|---|---|---|
| 幂等 | Confirm 或 Cancel 可能被重复调用 | 用事务状态表或唯一业务号防重复 |
| 空回滚 | Try 没执行成功,Cancel 却被调用 | Cancel 里先判断是否有 Try 记录 |
| 悬挂 | Cancel 先到,Try 后到 | Try 执行前检查是否已经 Cancel |
简单说:TCC 性能好,但不是加三个方法名就完了。它把一致性控制更多交给业务代码,所以业务状态表、幂等控制和异常分支处理都要自己设计。
MQ 最终一致
MQ 方案通常用于最终一致场景。
比如借款业务:
- 支付宝服务审核通过。
- 本地事务里生成借款单。
- 同一个事务内发送 MQ 消息。
- 借呗服务消费消息。
- 借呗服务执行自己的本地事务。
- 消费失败时重试或进入补偿流程。
MQ 方式性能最好,但不是强一致,它依赖消息可靠投递、消费幂等和补偿机制。
方案怎么选
| 方案 | 一致性 | 性能 | 开发成本 | 适合场景 |
|---|---|---|---|---|
| XA | 强一致 | 较差 | 较低 | 银行、资金强一致 |
| AT | 最终一致倾向 | 较好 | 较低 | 常见互联网业务 |
| TCC | 最终一致倾向 | 较好 | 高 | 复杂业务资源预留 |
| MQ | 最终一致 | 最好 | 中等 | 异步解耦、通知、跨服务写 |
面试回答模板
可以这样答:
我们项目中只要涉及多个服务之间的写操作,就要考虑分布式事务。Seata 里有三个角色:TC 是事务协调者,维护全局事务和分支事务状态;TM 负责开启、提交或回滚全局事务;RM 管理分支事务资源,并向 TC 注册和汇报状态。Seata 有 XA、AT、TCC 等模式。XA 是强一致,两阶段中一阶段执行 SQL 但不提交,二阶段统一提交或回滚,性能较差。AT 模式一阶段提交本地事务并记录 undo log,回滚时用 undo log 恢复,性能更好。TCC 需要业务实现 Try、Confirm、Cancel。MQ 方案是异步最终一致,性能最好,但要保证消息可靠和消费幂等。
小结
分布式事务不要只背方案名。
先问业务需要什么:强一致、最终一致、性能、开发成本、失败补偿能力。把这个取舍讲清楚,方案选择才站得住。
