直接切入:先从一个真实场景说起。微服务架构下,订单服务和库存服务分开部署,各自拥有独立数据库。用户下单时,订单库写入一条订单记录,库存库扣减一个库存数量。看起来很简单,但一旦库存扣减成功、订单写入失败,或者订单写入成功、库存扣减超时,数据就对不上了。这类问题就是分布式事务要解决的。而SEATA作为国内使用率极高的分布式事务框架,提供了AT、TCC、Saga、XA四种模式。其中XA模式因为实现简单、对业务代码侵入小,成了很多团队的入门首选,也是面试中最高频被问到的点。
这篇文章我从原理到实操,把SEATA的XA模式讲透。适合刚接触分布式事务的开发者,也适合准备面试、或者正在做技术选型的朋友。我会把XA模式的两阶段提交机制、TM/TC/RM三个角色的协作方式、Spring Boot工程怎么接入、以及我在生产环境里踩过的坑全部拆开讲。读完你不仅能跑通一个XA模式的示例,还能搞清楚为什么它“简单”,以及它到底“牺牲”了什么。
1. 理解分布式事务以前,先看一个具体的业务场景
1.1 从一次下单扣库存说起
假设你有一个电商系统,拆成了订单服务(Order Service)和库存服务(Inventory Service)。订单服务负责插入订单数据,库存服务负责扣减库存。两个服务各自连接不同的数据库,甚至部署在不同机房。此时用户发起一次购买请求,系统要完成两步操作:
- 订单服务在自己的数据库里新增一条订单记录,状态为“待支付”。
- 库存服务在自己的数据库里扣减对应商品库存,如果库存不足则报错。
在单体应用时代,这两步操作可以放在同一个本地事务里,要么都成功,要么都失败。但微服务拆开后,事务边界被打破了——订单服务无法感知库存服务的内部事务,库存服务也无法回滚订单服务已经提交的数据。于是就会出现:订单创建成功,但库存扣减失败,用户看到订单存在,却永远无法发货;或者库存扣减成功,但订单创建失败,商品被白白占住。
更麻烦的是,如果中间还有支付、优惠券、积分等服务,链条越长,数据不一致的概率越高。这个问题的本质是:如何让多个独立数据库上的操作,在业务上保持原子性。这就是分布式事务要解决的核心问题。
1.2 分布式事务的常见解决方案
行业内对分布式事务的探索很多,大致可以分成两类方向。
第一类是强一致性方案,典型代表是XA协议(两阶段提交)。XA是一个数据库层面的标准协议,由X/Open组织提出,几乎所有主流关系型数据库(MySQL、Oracle、PostgreSQL等)都原生支持。它的特点是:多个数据库参与同一个全局事务,事务管理器(Transaction Manager)协调所有参与者,要么全部提交,要么全部回滚,中间不会出现部分成功的情况。缺点是性能损耗大,因为事务过程中数据库资源一直被锁住,并发能力会明显下降。
第二类是最终一致性方案,典型代表是TCC(Try-Confirm-Cancel)、Saga、本地消息表、消息事务等。这类方案牺牲了强一致性,允许在某个时间点出现短暂的不一致,但通过补偿机制最终达到一致。优点是性能好、扩展性强,缺点是需要业务方自己实现大量的补偿逻辑,开发成本高。
SEATA框架把这几种方案全部收编了。AT模式相当于对XA的改良,通过数据快照和全局锁实现类似效果,但没有XA那么重的资源锁;TCC需要业务方实现三个方法;Saga适合长流程;而XA模式最直接,数据库原生支持,代码侵入最小。接下来重点讲XA模式。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. SEATA中的XA模式:核心角色与原理
2.1 TM、TC、RM 三个角色
SEATA框架定义了三个核心角色,理解这三个角色是掌握XA模式的关键。
- TC(Transaction Coordinator):事务协调器,独立部署的Seata Server。它负责全局事务的注册、分支事务的登记、全局提交或回滚指令的下发。你可以把它理解成“总指挥”。
- TM(Transaction Manager):事务管理器,通常嵌入在发起全局事务的业务服务里。它负责向TC申请开启一个全局事务,然后根据业务执行结果,向TC发起全局提交或全局回滚。
- RM(Resource Manager):资源管理器,负责管理分支事务的资源。在XA模式里,RM就是对数据库XA连接的管理。当业务代码里执行SQL时,RM会向TC注册分支事务,并参与全局事务的提交或回滚。
以订单服务为例:订单服务的业务方法上标注了@GlobalTransactional注解,这个方法就是全局事务的入口。TM在方法开始时向TC申请全局事务ID,然后方法内所有对数据库的操作(包括调用库存服务),都会通过RM把分支事务注册到TC上。最终方法执行成功,TM通知TC提交全局事务;如果方法抛出异常,TM通知TC回滚全局事务。
这个过程中,TC是全局事务的核心,它需要高可用部署。
