XA 强一致性分布式事务原理与实战
约 3208 字大约 11 分钟
2026-05-25
分布式事务是分布式系统开发中的一大挑战,XA 协议作为经典的强一致性解决方案,基于 两阶段提交(2PC) 协议来保证所有事务参与者要么全部成功,要么全部失败。本文将深入剖析 XA 协议的原理,并通过 Seata 框架实现 XA 模式的实际应用。
分布式事务与 XA 协议
分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统节点上。XA是由X/Open组织提出的分布式事务处理(DTP,Distributed Transaction Processing)规范,旨在保证分布式事务的强一致性(ACID原则),几乎所有主流数据库(如MySQL、Oracle等)都对XA规范提供了支持。
XA协议通过 两阶段提交(2PC) 机制,协调多个 资源管理器(RM),确保在分布式事务中,所有参与者要么全部提交,要么全部回滚。
在DTP模型中,核心组件包括:
应用程序(AP):定义事务边界(即事务的开始和结束),并在事务边界内对资源进行操作。
事务管理器(TM):负责分配事务唯一标识,监控事务的执行进度,并负责事务的提交、回滚等。在Seata中,TM通常指开启了全局事务的业务程序。
资源管理器(RM):如数据库、文件系统等,并提供访问资源的方式。在Seata中,RM指参与分布式事务的每个微服务。
XA协议原理剖析:两阶段提交(2PC)
XA 协议的核心是两阶段提交(2PC),其基本思想是将事务的提交过程分为两个阶段来执行。
阶段一:准备阶段
准备阶段的主要目的是 确认所有事务参与者是否都准备好提交事务,具体步骤如下:
协调者询问:事务协调者(TM)向所有参与者(RM)发送事务内容,询问是否可以提交事务,并等待所有参与者答复。
参与者执行:各参与者执行事务操作,将Undo和Redo信息记入事务日志中(但不提交事务)。
参与者反馈:如果参与者执行成功,给协调者反馈Yes(可以提交);如果执行失败,则反馈No(不可提交)。
阶段二:提交阶段
提交阶段的主要目的是根据 准备阶段的反馈结果,决定是真正提交事务还是回滚事务:
场景一:所有参与者均反馈Yes
协调者提交请求:协调者向所有参与者发出正式提交事务的请求(即Commit请求)。
参与者提交:参与者执行Commit请求,并释放整个事务期间占用的资源。
参与者确认:各参与者向协调者反馈Ack(应答)完成的消息。
完成事务:协调者收到所有参与者反馈的Ack消息后,完成事务提交。
场景二:任何参与者反馈No或超时
协调者回滚请求:协调者向所有参与者发出回滚请求(即Rollback请求)。
参与者回滚:参与者使用阶段一中的Undo信息执行回滚操作,并释放整个事务期间占用的资源。
参与者确认:各参与者向协调者反馈Ack完成的消息。
完成中断:协调者收到所有参与者反馈的Ack消息后,完成事务中断。
2PC的优缺点
优点:
强一致性:满足ACID原则,是分布式事务强一致性的经典解决方案。
简单易懂:方案实现起来相对简单,主要数据库都支持,对业务侵入低。
缺点:
同步阻塞问题:所有参与者在事务提交阶段处于同步阻塞状态,占用系统资源,容易导致性能瓶颈。
单点故障问题:如果协调者(TM)出现故障,参与者(RM)将一直处于锁定状态。
数据一致性问题:在阶段二中,如果发生局部网络问题,一部分参与者收到了提交消息,另一部分没收到,会导致节点间数据不一致。
Seata XA 模式深度解析
XA 模式是从 1.2 版本支持的事务模式,Seata XA 模式是利用事务资源(数据库、消息服务等)对 XA 协议的支持,以 XA 协议的机制来管理分支事务的一种事务模式。Seata 对 XA 模式进行了封装,使其更易于在微服务架构中使用。
主要特点:
- 采用
DataSourceProxyXA作为数据源代理,替代AT模式的DataSourceProxy - 通过
@GlobalTransactional注解标记分布式事务入口 - 在第一阶段,RM 执行业务 SQL 但不提交,只注册分支事务
- 在第二阶段,由 TM 根据分支状态决定提交或回滚
Seata架构与 XA 模式流程

在 Seata 定义的分布式事务框架内,XA 模式利用事务资源(数据库等)对 XA 协议的支持,以 XA 协议的机制来管理分支事务。
执行阶段(Execute):
开启全局事务:TM 向 TC(Seata-Server)发起全局事务的开启请求,TC生成全局唯一的XID。
注册分支事务:每个 RM 执行业务 SQL 前,会向TC注册分支事务,并将XID与本地事务关联。
执行SQL并准备:RM执行业务SQL,但不提交(数据库层面由XA驱动管理),然后执行xa_prepare(或等效操作)。
报告状态:RM 将本地事务执行状态(成功或失败)报告给 TC。
完成阶段(Finish):
TC决策:TC 根据所有分支事务的报告状态决定全局事务是提交还是回滚。
提交/回滚:TC 通知所有 RM 执行
xa_commit或xa_rollback。资源释放:RM 完成最终操作并释放事务资源。
Seata XA 模式的数据源代理设计对开发者友好,旨在透明化 XA 编程模型。它支持基于普通 DataSource 创建 XA 连接,无需开发者专门配置 XADataSource
Seata XA 模式存在的问题
数据锁定
数据在整个事务处理过程结束前,都被锁定,读写都按隔离级别的定义约束起来。
::: tip思考 数据锁定是获得更高隔离性和全局一致性所要付出的代价。
补偿型 的事务处理机制,在 执行阶段 即完成分支(本地)事务的提交,(资源层面)不锁定数据。而这是以牺牲 隔离性 为代价的。
另外,AT 模式使用 全局锁 保障基本的 写隔离,实际上也是锁定数据的,只不过锁在 TC 侧集中管理,解锁效率高且没有阻塞的问题。 :::
协议阻塞
XA prepare 后,分支事务进入阻塞阶段,收到 XA commit 或 XA rollback 前必须阻塞等待。
::: tip思考
协议的阻塞机制本身并不是问题,关键问题在于 协议阻塞 遇上 数据锁定。
如果一个参与全局事务的资源 “失联” 了(收不到分支事务结束的命令),那么它锁定的数据,将一直被锁定。进而,甚至可能因此产生死锁。
这是 XA 协议的核心痛点,也是 Seata 引入 XA 模式要重点解决的问题。
基本思路是两个方面:避免 “失联” 和 增加 “自解锁” 机制。 :::
性能差
性能的损耗主要来自两个方面:一方面,事务协调过程,增加单个事务的 RT;另一方面,并发事务数据的锁冲突,降低吞吐。
::: tip思考
和不使用分布式事务支持的运行场景比较,性能肯定是下降的,这点毫无疑问。
本质上,事务(无论是本地事务还是分布式事务)机制就是拿部分 性能的牺牲 ,换来 编程模型的简单 。
与同为 业务无侵入 的 AT 模式比较:
首先,因为同样运行在 Seata 定义的分布式事务框架下,XA 模式并没有产生更多事务协调的通信开销。
其次,并发事务间,如果数据存在热点,产生锁冲突,这种情况,在 AT 模式(默认使用全局锁)下同样存在的。
所以,在影响性能的两个主要方面,XA 模式并不比 AT 模式有非常明显的劣势。
AT 模式性能优势主要在于:集中管理全局数据锁,锁的释放不需要 RM 参与,释放锁非常快;另外,全局提交的事务,完成阶段 异步化。 :::
Seata XA 模式的优缺点
优点:
强一致性:得益于 XA 协议,满足 ACID 特性。
数据库支持广泛:主流支持 XA 协议的数据库均可使用。
低侵入性:开发者通常只需关注
@GlobalTransactional注解,无需深入修改业务代码。
缺点:
性能开销:一阶段需要锁定数据库资源,直到二阶段结束才释放,在高并发场景下对性能影响较大。
依赖数据库 XA 支持:其能力依赖于底层数据库对 XA 协议的实现质量。
Spring Cloud Alibaba 集成 Seata XA 模式实战
接下来我们设计一套基于 Seata XA 模式的分布式事务实现方案。
环境准备
Seata Server (TC):已部署并运行,并使用 Nacos 作为注册中心和配置中心。
支持XA的数据库:如MySQL 5.7.17及以上版本。
基于 Spring Cloud Alibaba 构建 cloud-seata-xa 项目,模块如下
- cloud-seata-xa-order
- cloud-seata-xa-account
- cloud-seata-xa-storage
代码实现可下载 cloud-seata-xa
::: tip提示 从编程模型上,XA 模式与 AT 模式保持完全一致,只需要修改数据源代理,即可实现 XA 模式与 AT 模式之间的切换。 :::
Naocs 配置
在同分组下,根据服务中 seata.service.vgroup-mapping 定义的分组名称配置信息,内置的文本为集群名称 default。
seata:
# 是否开启spring-boot自动装配 默认true
enabled: true
# 是否开启数据源自动代理 默认 true
enable-auto-data-source-proxy: true
# 是否使用JDK代理作为数据源自动代理的实现方式,默认false,采用CGLIB作为数据源自动代理的实现方式
use-jdk-proxy: false
# 数据源代理模式 默认 AT
data-source-proxy-mode: XA
# Seata 应用ID,默认${spring.application.name}
application-id: ${spring.application.name}
# 事务分组 - 用于TC集群名
tx-service-group: seata-xa-group
# 添加以下配置
service:
vgroup-mapping:
seata-xa-group: default # 你的事务分组对应的集群名称
disable-global-transaction: false
XA模式优缺点与适用场景
优点总结
强一致性:严格遵循ACID,数据一致性高。
模型简单:理解和使用相对简单,尤其是与Seata集成后。
数据库原生支持:依赖数据库自身XA实现,稳定可靠。
无代码侵入(低侵入):业务代码几乎无需为分布式事务做额外修改。
缺点总结:
性能瓶颈:同步阻塞和资源锁定时间长,吞吐量低,不适合高并发场景。
依赖数据库:性能和质量受数据库XA实现影响。
单点问题:TM(协调者)宕机可能导致资源阻塞(虽然后续有Seata TC保障,但传统2PC存在此问题)。
适用场景
对强一致性要求极高的业务场景,如金融核心交易。
事务执行时间相对确定且较短的操作。
系统并发量不是极端高,可以接受XA协议性能损耗的场景。
总结
XA 协议通过两阶段提交(2PC) 机制,为分布式事务提供了强一致性的保证,是分布式事务领域经典且重要的解决方案。Seata 框架对 XA 进行了封装和优化,降低了开发复杂度,使得开发者能够通过简单的注解和配置,快速在微服务体系中引入强一致性分布式事务能力。
然而,XA 协议的同步阻塞和性能问题也是其固有的局限性。因此,在选择分布式事务方案时,需要根据实际业务场景对一致性和性能的要求进行权衡。对于追求高性能和最终一致性的场景,可以考虑 Seata 的 AT 模式或TCC 模式等柔性事务方案。