Seata分布式事务框架及XA模式
笔者参与了OSPP-2025开源之夏 Seata社区的议题:Seata-Go与Seata-Java版本拉齐,在实现XA模式支持PostgreSQL数据库的时候,通过写测试,发现自己对Seata、对XA模式的理解,还不够深刻,故查阅源码、官网文章,针对自己不懂的、理解有误的,整理出一篇笔记。
相关连接:
1. 怎么理解Seata分布式事务框架
1.1 三个角色
想象一个特殊的场景:
一个小公司承包了一个建筑项目,这个小公司的组成是,一堆工人(RM),一个管理所有工人包工头(TM),一个记下来哪个工人干啥的会计(TC)。
这个包工头(TM)非常奇葩,他的要求是,要么所有工人(RM)做的事都做成功了,才能下班;一旦有一个工人(RM)做的工作失败了,则所有人的工作全部毁掉,回到原始状态。
工地开工前,包工头(TM)拿着图纸找到会计(TC):“今天要完成地基+砌墙+铺水电,给这个活儿编个号(XID),记着——要么全成,要么全拆。”
会计点点头,在账本上记下:“项目XID=001,状态:开始”。
包工头转身给三个工人(RM1、RM2、RM3)派活:“地基归你(RM1),砌墙归你(RM2),水电归你(RM3),都记着用XID=001找会计登个记。”
工人开工时,都先跑去找会计:“我干地基,归XID=001”“我干砌墙,归XID=001”……会计在账本上补全:“XID=001关联:RM1(地基)、RM2(砌墙)、RM3(水电),状态:施工中”。
半天后:
- RM1回来告诉包工头:“地基好了”,转头跟会计说:“我的活成了(可提交)”;
- RM2也说:“墙砌完了”,跟会计报备:“我的活成了(可提交)”;
- RM3却满头大汗:“水管爆了,搞砸了”,跟会计说:“我的活废了(可回滚)”。
包工头一听,立刻喊会计:“XID=001全拆了!”
会计翻出账本,对着三个工人的名字喊:“RM1拆地基,RM2拆墙,RM3处理烂摊子!” 等所有人恢复原状,会计在账本上改:“XID=001状态:已回滚”。
——这就是三个角色的协作:包工头(TM)定规则、做决策;工人(RM)干活、向会计报备;会计(TC)记账、传指令,最终保证“要么全成,要么全拆”。
这样你就理解Seata中最重要的三个角色,TC、TM、RM
- TC:Transaction Coordinator 事务协调器
- TM:Transaction Manager 事务管理者
- RM: Resource Manager 资源管理器
1.2 如何理解Seata事务模式
Seata官网文章这块用TCC、AT模式举例,已经很清楚了,不会有不懂的地方
2. XA模式
2.1 什么是XA
XA 是 分布式事务领域的经典协议,核心作用是解决“跨多个数据库/服务的事务一致性”问题——简单说,就是保证“多个操作要么全成,要么全败”,和我们之前理解的“要么全下班,要么全拆活”逻辑一致。
2.1.1 XA 的核心:2个角色 + 2个阶段
XA 协议里只有两种关键角色,职责清晰,流程分两步走,没有多余复杂逻辑:
(1)2个核心角色
| 角色 | 职责 | 对应 Seata 角色 |
|---|---|---|
| 协调者(Coordinator) | 管全局:发起事务、收集结果、发最终指令 | 包工头(TM)+ 会计(TC) |
| 参与者(Participant) | 干本地活:执行自己的操作、响应指令 | 工人(RM) |
(2)2个执行阶段(核心逻辑)
XA 的一致性靠“两阶段提交(2PC)”实现,两步走完整个流程:
阶段1:准备阶段(投票阶段)——“先试试能不能干成”
- 协调者(包工头+会计)对所有参与者(工人)说:“你们先把自己的活干了,但别收尾(比如工人别把最后一块砖砌死、别把水管封死),干完了告诉我‘能成’还是‘不能成’。”
- 每个参与者(工人):
- 如果自己的活能顺利执行(比如地基能打、墙能砌),就先“冻结”结果(不提交),然后告诉协调者“我这能成(Yes)”;
- 如果自己的活干砸了(比如水管爆了),直接告诉协调者“我这不行(No)”,同时自己先把烂摊子清掉(回滚自己的操作)。
- 协调者收集所有参与者的“投票结果”。
阶段2:提交/回滚阶段(执行决策)——“要么全成,要么全拆”
协调者根据收集到的投票,做最终决策:
- 如果所有参与者都投“能成(Yes)”:协调者发指令“所有人提交!”,参与者(工人)再做收尾操作(砌死最后一块砖、封死水管),事务完成;
- 只要有一个参与者投“不能成(No)”:协调者发指令“所有人回滚!”,参与者(工人)把自己干的活拆了(拆地基、拆墙),回到最初状态。
2.1.2 XA 的关键特点
- 强一致性:能严格保证“要么全成要么全败”,适合对一致性要求极高的场景(比如银行转账:A账户扣钱、B账户加钱,必须同时成功);
- 缺点:阻塞风险:如果某个参与者(工人)卡壳了(比如干到一半没动静),协调者会一直等它的反馈,导致整个事务卡住(所有人都得等这个工人)。
总结:XA 是“用两步流程+明确分工”,把分布式事务的一致性逻辑标准化了——本质就是“先确认所有人都能行,再最终执行;只要有一个不行,就全撤回”。
2.2 为什么要在Seata框架中支持XA模式
本质上,Seata支持的其他三种模式,AT、TCC、Saga都是补偿型的,补偿型 事务处理机制构建在 事务资源 之上(要么在中间件层面,要么在应用层面),事务资源 本身对分布式事务是无感知的。
- 补偿型事务:Seata 的 AT、TCC、Saga,本质都是 “先执行本地操作,出问题了再用‘补偿操作’回滚”(比如扣库存错了,就用 “加库存” 补偿),而不是像 XA 那样 “先确认所有操作能成,再最终提交”。
- 事务资源无感知:这里的 “事务资源” 就是底层的数据库(或缓存、MQ 等),它只负责执行 “本地 CRUD”(比如库存 100→50 的更新),完全不知道这个操作是 “分布式事务的一部分” —— 它以为自己只是在执行一个普通的本地小事务,所以执行完就直接提交了,不会等 “全局事务的最终决策”。
核心点在于,补偿型的事务中,只会保证最终一致性,中间状态会被看到,难以保证全局一致性。
而Seata设计XA模式,本质就是对全局一致性事务管理模式的支持。
如何实现XA模式
链接
