Seata 的 XA 模式是基于 X/Open XA 规范 实现的分布式事务方案,核心目标是保证分布式事务的 强一致性。它通过事务协调器(TC)与数据库原生的 XA 协议能力协同,适用于对数据一致性要求极高、可接受一定性能损耗的业务场景。
一、核心定位:“强一致”的分布式事务
- XA 模式的核心是遵循 两阶段提交(2PC)协议,依赖数据库原生的 XA 接口(如 MySQL 的 XA START/END/PREPARE/COMMIT/ROLLBACK 命令),实现“所有节点要么一起提交,要么一起回滚”的强一致效果。
- 与 AT 模式的“无侵入”不同,XA 模式虽无需业务代码改造,但需数据库支持 XA 协议(如 InnoDB 引擎),且性能低于 AT 模式,是典型的“一致性优先于性能”方案。
如果对AT模式也感兴趣可以看看这篇 Seata的AT模式详细介绍
二、核心原理:三组件 + 标准 2PC 流程
Seata XA 模式同样依赖 TC(事务协调器)、TM(事务管理器)、RM(资源管理器) 三大组件,但 RM 的实现与 AT 模式不同——XA 模式的 RM 直接对接数据库的 XA 接口,而非通过快照和 undo_log 表。
1. 核心组件分工(与 AT 模式差异点)
TC:职责与 AT 模式一致,负责生成全局事务 ID(xid)、协调所有 RM 完成“预提交”和“最终提交/回滚”,是 2PC 流程的核心调度者。
TM:作为全局事务发起者,通过 @GlobalTransactional 注解触发事务,向 TC 注册全局事务,并传递 xid 给各 RM 节点。
RM:与 AT 模式的“快照+本地提交”不同,XA 模式的 RM 是 数据库 XA 接口的封装,负责执行本地 SQL 并响应 TC 的“预提交”“回滚”指令,依赖数据库自身完成事务状态管理。
2. 标准 2PC 执行流程(以“订单创建 + 库存扣减”为例)
假设全局事务包含 订单服务(TM,连接订单库) 和 库存服务(RM,连接库存库),两阶段流程如下:
阶段一:Prepare(预提交)
1.初始化全局事务:订单服务(TM)触发 @GlobalTransactional 方法,向 TC 申请全局事务 ID(xid),并将 xid 通过 RPC 传递给库存服务。
2.开启 XA 分支事务:
-
库存服务(RM)接收到 xid 后,向库存库发送 XA START 'xid-分支ID' 命令,开启一个 XA 分支事务。
-
执行本地业务 SQL(如 update stock set num=num-1 where id=1),此时 SQL 已执行但未提交,数据处于“锁定待确认”状态。
3.执行预提交:
- 库存服务(RM)向库存库发送 XA PREPARE 命令,数据库会检查当前事务的完整性(如是否有锁冲突、SQL 语法错误),若通过则将事务状态标记为“可提交”,并持有相关数据锁(防止其他事务修改);若失败则直接返回“预提交失败”。
4.反馈预提交结果:库存服务(RM)将“预提交成功/失败”结果上报给 TC;订单服务执行完自身 XA 分支事务后,也向 TC 上报结果。
阶段二:Commit/Rollback(最终提交/回滚)
- TC 收集所有 RM 的预提交结果后,决定全局事务的最终操作,且该操作具有“原子性”——要么所有节点提交,要么所有节点回滚:
•情况1:所有 RM 预提交成功 → 全局提交
1.TC 向所有 RM 发送“全局提交”指令。
2.各 RM 收到指令后,向数据库发送 XA COMMIT 'xid-分支ID' 命令,数据库确认提交事务,释放数据锁。
3.各 RM 向 TC 反馈“提交成功”,全局事务结束,数据完全一致。 情况2:任一 RM 预提交失败 → 全局回滚
1.TC 向所有 RM 发送“全局回滚”指令。
2.各 RM 收到指令后,向数据库发送 XA ROLLBACK 'xid-分支ID' 命令,数据库撤销之前执行的 SQL,释放数据锁。
3.各 RM 向 TC 反馈“回滚成功”,全局事务结束,数据恢复到初始状态。
三、关键特性
1.强一致性:严格遵循 2PC 协议,“预提交成功则必提交,预提交失败则必回滚”,不存在 AT 模式“阶段一提交后阶段二回滚”的短暂数据不一致问题。
2.数据库原生支持:依赖数据库自身的 XA 协议实现,无需 Seata 框架额外维护 undo_log 表(区别于 AT 模式),减少框架与业务库的耦合。
3.低业务侵入:与 AT 模式类似,仅需通过 @GlobalTransactional 注解标记全局事务入口,无需修改业务 SQL 或编写补偿逻辑。
4.故障可恢复:若 TC 或 RM 在流程中宕机,数据库会保留 XA 事务的“预提交”状态,恢复后可通过 TC 重新发起“提交/回滚”指令,避免数据丢失或不一致。
四、局限性
1.性能较低:
-
阶段一“预提交”后,数据库会持有数据锁直到阶段二“最终提交/回滚”,锁持有时间远长于 AT 模式(AT 模式阶段一已提交,锁释放更快),高并发场景下会导致事务排队,吞吐量显著下降。
-
2PC 流程需多轮 TC 与 RM、RM 与数据库的通信,网络开销较大。
2.依赖数据库 XA 支持:仅适用于支持 XA 协议的关系型数据库(如 MySQL InnoDB、Oracle、PostgreSQL),无法用于非关系型数据库(如 Redis、MongoDB)或无 XA 接口的第三方服务(如支付 API)。
3.“阻塞”风险:若阶段二执行时 TC 宕机,RM 会一直持有数据锁等待指令,可能导致其他事务长期阻塞,需依赖 TC 故障恢复机制(如日志重演)解决。
五、适用场景
XA 模式是 Seata 中“强一致性”的专属方案,适合对 数据一致性要求极高、并发量中等或较低 的业务场景,例如:
-
金融核心业务(如银行转账、证券交易、基金申购):需严格保证“扣款”与“到账”的原子性,不允许任何数据不一致。
-
账务核对场景(如财务记账、对账系统):需确保多节点的账务记录完全一致,避免出现“单边账”。
-
对数据一致性要求高于性能的内部业务系统(如后台订单审核、库存盘点)。
六、与 AT 模式的核心差异
| 对比维度 | XA 模式 | AT 模式 |
|---|---|---|
| 一致性级别 | 强一致(2PC 协议) | 最终一致(快照+本地提交) |
| 锁持有时间 | 长(从预提交到最终提交/回滚) | 短(阶段一本地提交后即释放锁) |
| 依赖组件 | 数据库 XA 协议(无需 undo_log) | 数据库行锁 + Seata undo_log 表 |
| 性能 | 较低(高并发下易阻塞) | 较高(吞吐量优于 XA) |
| 适用场景 | 金融级强一致场景 | 常规微服务最终一致场景 |