Seata 2.6.0 AT 分布式事务:从部署、接入到故障边界
Seata 2.6.0 AT 分布式事务:从部署、接入到故障边界
本文基于 Seata 2.6.0、Spring Boot 3、Spring Cloud Alibaba 对应版本和 MySQL 8 编写。Seata、Spring Boot、Spring Cloud Alibaba、Nacos 和客户端依赖必须按官方兼容矩阵配套,不能只升级其中一个组件。
先说结论
Seata AT 适合一个业务操作需要修改多个关系型数据库、参与者可以接受短暂全局锁竞争、并且需要比最终一致性更强回滚语义的场景。
AT 不是“所有分布式操作自动回滚”。它不能自动撤销已经发送的消息、调用过的第三方 API、写入的缓存,也不能替代幂等、重试、补偿和可靠消息。
核心流程是:
应用线程
-> TM 开始全局事务
-> RM 代理本地数据源
-> TC 记录全局事务和分支事务
-> 数据库本地提交并保存 undo_log
-> TC 决定全局提交或回滚
一、组件和术语
- TC(Transaction Coordinator):保存全局事务、分支事务和全局锁。
- TM(Transaction Manager):负责开启、提交和回滚全局事务。
- RM(Resource Manager):负责注册分支、上报结果和执行本地回滚。
Seata 客户端通常同时包含 TM 和 RM:
订单服务(TM + RM)
-> 库存服务(RM)
-> 账户服务(RM)
|
v
Seata TC
@GlobalTransactional 通常放在全局事务入口。参与服务不需要再开启新的全局事务,但每个参与数据库的服务都必须正确接入 Seata 数据源代理。
二、AT 的真实执行过程
以一条 UPDATE 为例,RM 在本地事务中大致完成:
- 解析 SQL,识别表、主键和修改范围。
- 查询修改前的 before image。
- 执行业务 SQL。
- 查询修改后的 after image。
- 写入 undo_log。
- 注册分支事务并提交本地事务。
全局提交时,TC 通知各分支提交。一阶段已经完成本地提交,二阶段主要是异步清理 undo_log。
全局回滚时,RM 读取 undo_log,校验当前数据是否符合 after image,再根据 before image 生成反向操作,并在本地事务中执行回滚。
所以 AT 不是数据库快照,也不是一条固定反向 SQL。它依赖 SQL 解析、前后镜像、undo_log 和全局锁。
三、Seata 2.6.0 部署原则
当前参考版本为 Seata 2.6.0。不要使用 latest,也不要把 Seata 1.x 的配置文件、字段和数据库脚本直接复制到 2.x。
学习环境可以让 TC 使用 file 注册和 file 存储,先验证业务链路。生产环境通常应使用 Nacos 等注册中心和配置中心,并使用数据库或官方支持的高可用存储。
当 TC 使用 store.mode=db 时,应执行 Seata 2.6.0 发布包中对应数据库目录的 MySQL 脚本。脚本至少包含:
global_table 全局事务
branch_table 分支事务
lock_table 全局锁
distributed_lock TC 集群协调
vgroup_table 事务组映射
每个参与 AT 的业务数据库还需要执行同一版本客户端对应的 undolog 表脚本。TC 表和业务库的 undolog 不是同一类表。
AT 数据源通常要求:
- MySQL 使用 InnoDB;
- 业务表有稳定主键;
- SQL 能被 Seata 解析;
- 数据库账号有创建和写入 undo_log 的权限;
- undo_log、业务 SQL 和本地事务使用同一数据库连接边界。
Docker 镜像、JDK、客户端依赖和数据库脚本必须来自同一兼容方案。生产环境不要把 TC 管理端口暴露到公网。
四、Spring Boot 客户端接入
依赖版本不要手填一组互相独立的版本号。应根据 Spring Boot、Spring Cloud、Spring Cloud Alibaba 和 Seata 的兼容矩阵使用 BOM 或 dependency management。
配置概念如下,实际属性名以当前客户端版本的配置元数据为准:
seata:
enabled: true
tx-service-group: order_tx_group
enable-auto-data-source-proxy: true
data-source-proxy-mode: AT
使用 Nacos 时,注册中心和配置中心都要明确配置 server-addr、namespace、group、username 和 password。凭据通过环境变量或 secret 注入,不要提交到 Git。
启动后应确认:
- Seata 客户端已初始化;
- 数据源被 Seata 代理;
- RM 已注册到 TC;
- TM 已注册到 TC;
- 事务组已映射到可用 TC 集群。
多个数据源场景不要只依赖自动配置,应显式验证每个数据源的代理、Mapper 扫描和事务管理器。
五、业务示例
全局入口:
@Service
public class OrderApplicationService {
private final OrderMapper orderMapper;
private final InventoryClient inventoryClient;
private final AccountClient accountClient;
public OrderApplicationService(
OrderMapper orderMapper,
InventoryClient inventoryClient,
AccountClient accountClient) {
this.orderMapper = orderMapper;
this.inventoryClient = inventoryClient;
this.accountClient = accountClient;
}
@GlobalTransactional(
name = "create-order",
rollbackFor = Exception.class
)
public void create(Order order) {
orderMapper.insert(order);
inventoryClient.deduct(order.productId(), order.quantity());
accountClient.debit(order.userId(), order.amount());
}
}
参与服务负责本地业务:
@Service
public class InventoryService {
private final InventoryMapper inventoryMapper;
public InventoryService(InventoryMapper inventoryMapper) {
this.inventoryMapper = inventoryMapper;
}
@Transactional
public void deduct(long productId, int quantity) {
int affected = inventoryMapper.deduct(productId, quantity);
if (affected != 1) {
throw new IllegalStateException("库存不足");
}
}
}
关键不在注解数量,而在边界:
- 全局入口使用 @GlobalTransactional;
- 每个参与数据库的本地操作有清晰事务;
- 远程调用失败会抛出可识别异常;
- 库存扣减和账户扣款必须幂等;
- 重试不能重复扣库存或重复扣款。
如果使用 HTTP、RPC 或消息队列,必须确认 XID 能够传播。只在入口加注解但没有传播 XID,参与服务不会加入同一个全局事务。
六、AT 的失败边界
以下 SQL 必须重点验证:
- 复杂 JOIN、子查询和批量更新;
- 没有主键的表;
- 修改主键或分区键;
- 大批量数据更新;
- 存储过程、触发器和数据库特殊语法;
- 长事务和高竞争热点行。
不要只看业务方法返回成功,应通过故障注入测试确认回滚结果、锁释放和 undo_log 清理。
AT 不覆盖外部副作用:
数据库提交 -> 发送 MQ 消息 -> 调用支付接口 -> 写入 Redis
这些动作应根据业务选择 Outbox、本地消息表、可靠消息、幂等消费、状态机、补偿事务、TCC 或 Saga。
全局锁也不是免费能力。热点商品、账户和库存会形成锁竞争,导致分支注册变慢、事务等待、回滚变慢和线程池堆积。应缩短事务、避免事务内不必要的远程调用、按稳定顺序更新资源,并监控锁等待和回滚重试。
七、故障测试清单
至少测试:
- 库存服务超时;
- 账户服务返回业务失败;
- 一个分支本地提交后另一个分支失败;
- TC 重启;
- 数据库连接池耗尽;
- after image 校验失败;
- 重复请求和客户端重试;
- 网络响应丢失;
- 服务发布期间的版本兼容。
每次检查:
业务表最终状态
global_table
branch_table
lock_table
undo_log
日志中的 XID
线上日志应在请求、数据库分支、远程调用和异常日志中统一打印 XID,但不要打印密码、token 或敏感业务数据。
八、生产检查清单
- Seata Server、客户端、Spring Boot、Spring Cloud Alibaba 版本兼容。
- 所有镜像和依赖固定版本。
- TC 使用高可用部署,不使用 file 存储承载生产故障恢复。
- Nacos、数据库和 TC 通过内网访问。
- 配置和凭据通过 secret 或外部配置注入。
- 每个业务库都有对应版本的 undo_log。
- TC 数据库已备份并设置清理策略。
- 全局事务有超时、重试和降级策略。
- 外部副作用有幂等或补偿方案。
- 监控 XID、事务耗时、回滚率、锁等待、超时、重试和 undo_log 数量。
九、什么时候不要用 AT
以下情况通常应考虑其他方案:
- 事务跨越消息、支付、文件和第三方 API;
- 单个全局事务持续时间很长;
- 热点行竞争严重;
- SQL 无法稳定解析或没有主键;
- 业务更需要最终一致性;
- 团队没有能力维护 TC、数据库脚本、监控和故障演练。
Seata AT 不会把分布式系统变成单机事务。它是在适合的数据库边界内提供自动化协调和补偿机制。正确使用它的前提,是明确边界、固定版本、控制事务长度,并对失败路径做真实测试。
参考资料
- Seata 官方仓库与 v2.6.0 Release
- Seata AT Mode 官方文档
- Seata 2.6.0 同版本数据库脚本
- Spring Boot、Spring Cloud Alibaba 官方兼容矩阵
- Nacos 官方部署与鉴权文档
最后复核时间:2026-07。