Seata的AT、TCC、Saga模式的区别及适用场景?

一、Seata 三种模式核心概念

1. AT 模式(Auto Transaction)
  • 技术本质:基于两阶段提交的自动补偿型事务
  • 特点:通过全局锁实现数据隔离,业务代码零侵入
  • 实现原理
    // 业务方法示例
    @GlobalTransactional // 全局事务注解
    public void purchase() {
        // 1. 扣减库存(自动生成反向SQL)
        inventoryService.reduce();
        // 2. 创建订单(自动生成反向SQL)
        orderService.create();
    }
    
2. TCC 模式(Try-Confirm-Cancel)
  • 技术本质:手动补偿型事务
  • 核心接口
    public interface TccService {
        @TwoPhaseBusinessAction(name = "prepare", commitMethod = "commit", rollbackMethod = "rollback")
        boolean prepare(BusinessActionContext actionContext); // Try阶段
        
        boolean commit(BusinessActionContext actionContext);  // Confirm阶段
        boolean rollback(BusinessActionContext actionContext);// Cancel阶段
    }
    
3. Saga 模式
  • 技术本质:长事务解决方案
  • 执行方式
    // Saga状态机配置示例
    StateMachineBuilder<State, Event> builder = StateMachineBuilderFactory.create(...);
    builder.externalTransition()
        .from(State.WAIT_PAY)
        .to(State.PAID)
        .on(Event.PAY_SUCCESS)
        .perform(doAction()); // 正向操作
    

二、模式对比与实践场景

维度 AT 模式 TCC 模式 Saga 模式
一致性 最终一致 强一致 最终一致
侵入性 无侵入 需要实现TCC接口 需要定义补偿方法
适用场景 传统数据库操作(库存扣减) 金融交易(账户余额操作) 长流程业务(旅行订单)
锁机制 全局锁 无锁 无锁
回滚策略 自动生成反向SQL 手动实现Cancel逻辑 事件驱动补偿

三、实战代码案例

案例1:AT模式库存扣减(完整实现)
// InventoryService.java
public class InventoryService {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    // 库存扣减操作
    public void reduce(String commodityCode, int count) {
        jdbcTemplate.update("update inventory set count = count - ? where code = ?", count, commodityCode);
    }
}

// OrderService.java 
public class OrderService {
    @GlobalTransactional // 全局事务注解(核心控制点)
    public void createOrder(String userId, String commodityCode, int count) {
        // 生成订单记录
        jdbcTemplate.update("insert into orders(user_id,commodity_code,count) values(?,?,?)", 
            userId, commodityCode, count);
        // 调用库存服务
        inventoryService.reduce(commodityCode, count);
    }
}
案例2:TCC模式转账交易
// AccountTccServiceImpl.java
@Service
public class AccountTccServiceImpl implements AccountTccService {
    
    @Override
    @Transactional
    @TwoPhaseBusinessAction(name = "prepareDeduct", commitMethod = "commit", rollbackMethod = "rollback")
    public boolean prepareDeduct(BusinessActionContext context, String accountNo, BigDecimal amount) {
        // Try阶段:冻结金额
        int update = jdbcTemplate.update(
            "update account set frozen = frozen + ? where balance >= ? and account_no = ?", 
            amount, amount, accountNo);
        return update > 0;
    }

    @Override
    @Transactional
    public boolean commit(BusinessActionContext context) {
        // Confirm阶段:扣除冻结金额
        String accountNo = (String) context.getActionContext("accountNo");
        BigDecimal amount = (BigDecimal) context.getActionContext("amount");
        return jdbcTemplate.update(
            "update account set balance = balance - ?, frozen = frozen - ? where account_no = ?",
            amount, amount, accountNo) > 0;
    }

    @Override
    @Transactional
    public boolean rollback(BusinessActionContext context) {
        // Cancel阶段:释放冻结金额
        String accountNo = (String) context.getActionContext("accountNo");
        BigDecimal amount = (BigDecimal) context.getActionContext("amount");
        return jdbcTemplate.update(
            "update account set frozen = frozen - ? where account_no = ?",
            amount, accountNo) > 0;
    }
}
案例3:Saga模式旅行订单(事件编排)
// HotelBookingSaga.java
@Service
public class HotelBookingSaga {
    
    @SagaStart // Saga事务起点
    public void bookHotel(String orderId) {
        // 1. 预订酒店
        hotelService.book(orderId);
        // 2. 预订机票(自动触发补偿)
        flightService.book(orderId);
    }

    // 补偿方法(命名规范:业务方法名 + Compensate)
    public void bookHotelCompensate(String orderId) {
        hotelService.cancel(orderId);
        flightService.cancel(orderId);
    }
}

// FlightService.java
@Service
public class FlightService {
    @SagaService(compensate = "cancel")
    public void book(String orderId) {
        // 机票预订逻辑
    }
    
    public void cancel(String orderId) {
        // 机票取消逻辑
    }
}

四、配置要点(application.yml)

seata:
  enabled: true
  application-id: order-service
  tx-service-group: my_tx_group
  service:
    vgroup-mapping:
      my_tx_group: default
    enable-degrade: false
    disable-global-transaction: false
  config:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
  registry:
    type: nacos

五、生产环境选型建议

  1. AT模式:适用于传统数据库操作(库存系统/订单系统),需注意全局锁性能影响
  2. TCC模式:金融支付核心系统(资金账户操作),要求强一致性
  3. Saga模式:跨境物流订单(多系统协作的长流程业务),可接受最终一致性

建议搭配使用:核心交易系统使用TCC保证强一致,普通业务系统使用AT提升开发效率,跨多系统的长流程业务使用Saga管理事务边界。

你可能感兴趣的:(中间件,seata,python,开发语言)