Seata的XA模式详细介绍

97 阅读6分钟

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)
适用场景金融级强一致场景常规微服务最终一致场景