Seata中AT模式、TCC模式、Saga模式、XA模式介绍、应用场景和示例代码

概述

Seata的四种模式:AT、TCC、Saga和XA详细讲解。

1. AT 模式(Auto Transaction)​

核心原理

  • 两阶段提交

    • 阶段一(Branch Commit)​
      拦截业务 SQL,生成前置镜像(before image)和后置镜像(after image),保存到 UNDO_LOG 表。
      示例:执行 UPDATE product SET stock = stock - 10 WHERE id = 1 时,记录修改前的 stock=100 和修改后的 stock=90
    • 阶段二(Global Commit/Rollback)​
      全局事务提交时,删除 UNDO_LOG;回滚时,根据镜像数据生成反向 SQL(如 UPDATE product SET stock = 100 WHERE id = 1)。
  • 全局锁机制
    在阶段一提交前,Seata 会获取记录的全局锁,防止其他事务修改同一数据,确保隔离性。

应用场景

  • 单服务多数据源
    例如订单服务同时操作 MySQL 和 PostgreSQL,需要保证两个库的事务一致性。
  • 简单跨服务调用
    服务 A 调用服务 B 的接口,两者均使用 AT 模式(如订单服务扣减库存服务)。

代码示例

// 订单服务(使用 AT 模式)
@GlobalTransactional // 开启全局事务
public void createOrder(OrderRequest request) {
    // 1. 本地事务:创建订单
    orderDao.insert(request.getOrder());
    
    // 2. 远程调用库存服务(Feign 接口)
    storageFeignService.deduct(request.getProductId(), request.getCount());
    
    // 3. 模拟异常触发回滚
    if (request.getForceFail()) {
        throw new RuntimeException("Force rollback");
    }
}

关键细节

  • ​**UNDO_LOG 表结构**:需在业务库中提前创建,包含 branch_idxidrollback_info 等字段。
  • 隔离性牺牲:AT 模式默认隔离级别为读未提交(Read Uncommitted),高并发场景可能脏读,需业务侧处理(如版本号校验)。
  • 性能优化:避免单行数据频繁更新,防止全局锁竞争。

2. TCC 模式(Try-Confirm-Cancel)​

核心原理

  • 三阶段控制

    1. Try:预留资源(如冻结库存、预扣余额),完成业务检查。
    2. Confirm:确认操作,真正执行业务(如扣减冻结的库存)。
    3. Cancel:回滚操作,释放预留资源(如解冻库存)。
  • 业务侵入性:需手动编写 Try/Confirm/Cancel 接口,处理幂等性、空回滚、悬挂等问题。

应用场景

  • 资金交易:转账前预冻结账户金额,最终扣款或解冻。
  • 第三方服务集成:调用外部 API(如支付接口)需要明确的成功/失败确认。

代码示例

// TCC 接口定义(账户扣款)
public interface AccountTccService {
    @TwoPhaseBusinessAction(name = "deduct", commitMethod = "confirm", rollbackMethod = "cancel")
    boolean tryDeduct(@BusinessActionContextParameter(paramName = "userId") String userId,
                     @BusinessActionContextParameter(paramName = "amount") BigDecimal amount);

    boolean confirm(BusinessActionContext context);
    boolean cancel(BusinessActionContext context);
}

// Try 阶段实现(冻结资金)
@Override
public boolean tryDeduct(String userId, BigDecimal amount) {
    if (accountDao.getAvailableBalance(userId).compareTo(amount) < 0) {
        throw new RuntimeException("余额不足");
    }
    accountDao.freeze(userId, amount); // 冻结资金
    return true;
}

// Confirm 阶段(实际扣款)
@Override
public boolean confirm(BusinessActionContext context) {
    String userId = (String) context.getActionContext("userId");
    BigDecimal amount = (BigDecimal) context.getActionContext("amount");
    accountDao.deduct(userId, amount);  // 扣减冻结金额
    accountDao.unfreeze(userId, amount); // 解冻
    return true;
}

// Cancel 阶段(解冻资金)
@Override
public boolean cancel(BusinessActionContext context) {
    String userId = (String) context.getActionContext("userId");
    BigDecimal amount = (BigDecimal) context.getActionContext("amount");
    accountDao.unfreeze(userId, amount);
    return true;
}

关键细节

  • 幂等性处理
    通过唯一事务 ID(xid)确保 Confirm/Cancel 只执行一次。
  • 空回滚问题
    Try 未执行但收到 Cancel 请求时,需插入标记记录,避免误解冻。
  • 悬挂问题
    Cancel 比 Try 先到达时,需通过状态判断拒绝后续 Try 操作。

3. Saga 模式

核心原理

  • 事件驱动流程
    将分布式事务拆分为多个本地事务,每个事务提交后触发下一个事务。若某个事务失败,按反向顺序执行补偿操作。
  • 补偿机制
    每个正向操作需定义对应的补偿方法(如 bookHotel() 对应 cancelHotel())。

应用场景

  • 长流程业务
    旅行预订(机票 → 酒店 → 租车)、电商订单(下单 → 支付 → 发货)。
  • 最终一致性场景
    接受中间状态短暂不一致,但最终一致。

代码示例

// Saga 流程编排(状态机或注解驱动)
@SagaService
public class OrderSagaService {
    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private PaymentService paymentService;

    @SagaStart
    public void createOrder(Order order) {
        // 1. 扣减库存
        inventoryService.deduct(order.getProductId(), order.getQuantity());
        
        // 2. 发起支付
        paymentService.pay(order.getUserId(), order.getAmount());
        
        // 3. 更新订单状态为成功
        order.setStatus("SUCCESS");
        orderDao.update(order);
    }

    @Compensate
    public void compensateOrder(Order order) {
        // 反向操作:释放库存、退款、订单状态回滚
        inventoryService.restore(order.getProductId(), order.getQuantity());
        paymentService.refund(order.getUserId(), order.getAmount());
        order.setStatus("FAILED");
        orderDao.update(order);
    }
}

关键细节

  • 状态机配置
    可通过 JSON 或注解定义 Saga 流程,明确每个步骤的补偿方法。
  • 超时管理
    设置 Saga 事务超时时间,避免流程长期悬挂。
  • 异步执行
    适合结合消息队列(如 RocketMQ)实现异步 Saga。

4. XA 模式

核心原理

  • 传统两阶段提交
    1. Prepare 阶段:所有参与者(数据库)锁定资源,返回就绪状态。
    2. Commit/Rollback 阶段:协调者根据 Prepare 结果提交或回滚。
  • 强一致性
    所有资源在 Prepare 阶段锁定,直到全局事务结束。

应用场景

  • 金融核心系统
    银行转账(必须保证双方账户同时成功或失败)。
  • 传统数据库集成
    旧系统迁移,依赖数据库原生 XA 协议。

代码示例

// XA 数据源配置
@Bean
public DataSource dataSource() {
    MysqlXADataSource xaDataSource = new MysqlXADataSource();
    xaDataSource.setUrl("jdbc:mysql://localhost:3306/db");
    xaDataSource.setUser("root");
    xaDataSource.setPassword("root");
    
    return new AtomikosDataSourceBean(xaDataSource);
}

// 业务方法(依赖 JTA)
@Transactional // 使用 JTA 事务管理器
public void transfer(String fromId, String toId, BigDecimal amount) {
    jdbcTemplate.update("UPDATE account SET balance = balance - ? WHERE id = ?", amount, fromId);
    jdbcTemplate.update("UPDATE account SET balance = balance + ? WHERE id = ?", amount, toId);
}

关键细节

  • 性能瓶颈
    全局锁持有时间长,高并发下吞吐量低。
  • 数据库支持
    需数据库支持 XA 协议(如 MySQL InnoDB、Oracle)。
  • 调试复杂
    XA 事务状态需通过数据库日志或 JTA 工具监控。

选型对比与决策树

对比维度

维度ATTCCSagaXA
一致性弱隔离(读未提交)强隔离(预留资源)最终一致性强一致性
性能高(短事务)中(两阶段控制)高(异步流程)低(长锁)
侵入性低(自动 UNDO_LOG)高(手动 TCC 接口)中(补偿方法)低(数据库支持)
适用场景简单跨服务/多数据源资金交易、第三方集成长流程业务金融核心、传统系统
容错能力自动回滚需处理空回滚、悬挂需补偿逻辑完备依赖数据库 XA 恢复

决策树

  1. 是否需要强一致性?
    • 是 → ​XA 模式​(金融场景)或 ​TCC 模式​(业务可控)。
    • 否 → 进入下一步。
  2. 是否为长流程业务?
    • 是 → ​Saga 模式​(如电商订单)。
    • 否 → 进入下一步。
  3. 是否希望低侵入?
    • 是 → ​AT 模式​(简单跨服务调用)。
    • 否 → ​TCC 模式​(精细化控制)。

总结

  • AT 模式:快速解决 80% 的分布式事务问题,适合微服务新手。
  • TCC 模式:应对资金、库存等核心资源操作,牺牲开发效率换取高可靠性。
  • Saga 模式:长流程业务的终极方案,需接受最终一致性。
  • XA 模式:传统系统兼容选择,性能敏感场景慎用。

实际开发中,可组合使用多种模式(如 AT + Saga),并配合消息队列、幂等设计、监控告警,构建健壮的分布式事务体系。

Seata支持的三种事务模式ATTCC)、SAGAXA,它们之间的区别如下: 1. ATTCC模式AT模式是通过“尝试、确认、取消”三个步骤来实现分布式事务的。在AT模式中,Seata会为每个分布式事务创建一个全局事务,该全局事务包含多个本地事务。当一个本地事务提交时,Seata会将该提交操作视为“尝试”操作;当所有本地事务都提交时,Seata会将所有提交操作视为“确认”操作;当任意一个本地事务提交失败时,Seata会将所有提交操作视为“取消”操作,并回滚所有本地事务。 2. SAGA模式SAGA模式是通过“补偿”操作来实现分布式事务的。在SAGA模式中,Seata会为每个分布式事务创建一个全局事务,该全局事务也包含多个本地事务。当一个本地事务提交时,Seata会将该提交操作视为“正向”操作;当任意一个本地事务提交失败时,Seata会通过已经定义好的“补偿”操作来回滚相关的本地事务。 3. XA模式XA模式是通过全局事务管理器来实现分布式事务的。在XA模式中,Seata会为每个分布式事务创建一个全局事务,并通过JTA来实现全局事务的管理。当一个本地事务提交时,Seata会将该提交操作视为“参与”操作;当所有本地事务都参与时,Seata会将所有参与操作视为“提交”操作;当任意一个本地事务参与失败时,Seata会将所有参与操作视为“回滚”操作,并回滚所有本地事务。 总的来说,AT模式适用于对数据一致性要求较高的场景SAGA模式适用于对数据一致性要求较低的场景XA模式则是在使用JTA的情况下用于实现分布式事务的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值