Alibaba 分布式事务 Seata

如果说 TCC 和 Saga 是分布式事务的“理论模式”,那么 Seata 就是将这些理论落地的“工业级武器”。

Seata(Simple Extensible Autonomous Transaction Architecture)是阿里巴巴开源、目前捐赠给 Apache 的顶级项目。它是目前 Java 微服务生态(Spring Cloud Alibaba, Dubbo 等)中最主流、最成熟的分布式事务解决方案。

简单来说,Seata 就像一个“事务总管”,它帮你处理了跨服务调用的复杂协调工作,让你只需加一个注解就能实现分布式事务。


🏛️ Seata 的核心架构(三大角色)

Seata 的架构设计非常经典,理解这三个角色是掌握 Seata 的关键:

  1. TC (Transaction Coordinator) - 事务协调者
    • 角色:它是独立部署的服务端(Seata Server),是分布式事务的“大脑”。
    • 职责:维护全局事务状态,指挥大家是提交还是回滚。
  2. TM (Transaction Manager) - 事务管理器
    • 角色:它是业务代码的入口(比如你的订单服务)。
    • 职责:定义事务边界。通过 @GlobalTransactional 注解告诉 Seata:“从这里开始,我要开启一个全局事务了”。
  3. RM (Resource Manager) - 资源管理器
    • 角色:它是具体的业务服务(比如库存服务、账户服务)。
    • 职责:管理本地数据库资源,执行具体的 SQL,并向 TC 汇报执行情况。

工作流程一句话总结:TM 发起请求 -> TC 生成全局事务 ID (XID) -> RM 执行本地事务并汇报 -> TC 决定全局提交或回滚。


🚀 Seata 的四大模式(核心干货)

Seata 最强大的地方在于它支持多种模式,适配不同的业务场景。

1. AT 模式 (Automatic Transaction) —— 最推荐,最常用

这是 Seata 的默认模式,也是它“火”起来的原因。

  • 原理无侵入。Seata 会自动拦截你的 SQL,在执行前生成“前镜像”(数据修改前的快照),执行后生成“后镜像”。这两份快照会被存入 undo_log 表。
  • 回滚机制:如果事务失败,Seata 会自动读取 undo_log,生成反向 SQL(比如把 UPDATE 变成反向 UPDATE)来恢复数据。
  • 优点:代码改动极小,几乎不需要写额外逻辑,开发效率最高。
  • 缺点:依赖数据库的本地事务,存在全局锁竞争(虽然时间很短)。
  • 适用:90% 的基于关系型数据库(MySQL, PostgreSQL)的微服务场景。

2. TCC 模式 —— 高性能,高侵入

TCC 理论的具体实现。

  • 原理:需要你在代码中手动实现 TryConfirmCancel 三个接口。
  • 优点:不依赖数据库锁,性能极高,适合高并发。
  • 缺点:代码量大,开发成本高,需要处理幂等和悬挂问题。
  • 适用:核心资金链路、秒杀场景、或者非数据库资源(如 Redis)的事务。

3. Saga 模式 —— 长事务

对应 Saga 理论。

  • 原理:通过状态机引擎,编排一系列的正向服务和补偿服务。
  • 适用:跨公司、跨系统的长流程业务(如:下单->支付->物流->积分)。

4. XA 模式 —— 强一致性

  • 原理:基于数据库原生的 XA 协议(两阶段提交 2PC)。
  • 特点:强一致性,但在提交前会一直锁定数据库资源,性能较差。
  • 适用:银行核心系统等对一致性要求极其严苛的场景。

🆚 四种模式对比与选型

模式 一致性 性能 侵入性 复杂度 适用场景
AT 最终一致性 ⭐⭐⭐⭐ 低 (无侵入) 首选,常规微服务业务
TCC 最终一致性 ⭐⭐⭐⭐⭐ 高 (需写3个方法) 高并发、核心交易、非DB资源
Saga 最终一致性 ⭐⭐⭐⭐ 中 (需写补偿) 长流程、跨系统、异步调用
XA 强一致性 ⭐⭐ 银行核心、遗留系统

💻 代码实战:AT 模式 (最常用)

在 Go 语言中,虽然 Seata 原生是 Java 的,但社区也有 Go 的客户端实现(或者使用 dtm 框架兼容 Seata 协议)。这里展示最经典的 Java/Spring Boot 写法,逻辑是通用的。

步骤 1:引入依赖与配置
(省略 Maven 配置,假设已集成 seata-spring-boot-starter

步骤 2:业务代码
只需要在入口方法加一个注解 @GlobalTransactional

@Service
public class OrderService {

    @Autowired
    private AccountService accountService;
    @Autowired
    private StockService stockService;

    // 1. 开启全局事务
    @GlobalTransactional
    public void createOrder(Order order) {
        // 2. 创建订单(本地事务)
        orderMapper.insert(order);
        
        // 3. 调用库存服务(远程调用,Seata 会自动传播 XID)
        stockService.deduct(order.getProductId(), order.getCount());
        
        // 4. 调用账户服务(远程调用)
        accountService.deduct(order.getUserId(), order.getAmount());
        
        // 如果上面任何一步抛出异常,Seata 会自动回滚所有操作
    }
}

步骤 3:数据库准备
使用 AT 模式时,每个业务数据库都需要创建一张 undo_log 表,用于 Seata 存储回滚日志。

CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
);

📌 总结

  • Seata 是什么? 一个开箱即用的分布式事务框架。
  • 怎么用? 部署一个 TC 服务端,业务端引入 SDK,加上 @GlobalTransactional 注解。
  • 选哪个模式? 默认选 AT 模式;搞不定性能瓶颈或涉及非数据库资源时选 TCC;流程特别长时选 Saga
posted @ 2026-04-21 13:25  干炸小黄鱼  阅读(68)  评论(0)    收藏  举报