当前位置: 首页 > ds >正文

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 {@Autowiredprivate 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@Transactionalpublic 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@Transactionalpublic 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: trueapplication-id: order-servicetx-service-group: my_tx_groupservice:vgroup-mapping:my_tx_group: defaultenable-degrade: falsedisable-global-transaction: falseconfig:type: nacosnacos:server-addr: 127.0.0.1:8848registry:type: nacos

五、生产环境选型建议

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

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

http://www.xdnf.cn/news/11040.html

相关文章:

  • 如何轻松删除 Android 上的文件(3 种方法)
  • lanqiaoOJ 1508:N皇后问题 ← dfs
  • Linux进程间通信(IPC)
  • TypeScript 中的字面量类型(Literal Types)
  • 什么是 Docker Compose 的网络(network),为什么你需要它,它是怎么工作的
  • 词语翻译的三步法与背后的语言学思维
  • R²AIN SUITE AI知识库助力中国制造业数字化转型
  • ABAP设计模式之---“高内聚,低耦合(High Cohesion Low Coupling)”
  • 嵌入式学习 D31:系统编程--Framebuf帧缓冲
  • java实用类
  • 【Agent智能体】吴恩达:AI智能体发展现状 | LangChain访谈--快速总结
  • 电脑远程桌面连接如何设置端口?默认修改和内网给外网访问方法
  • ArkUI-X中Plugin生命周期开发指南
  • 不连网也能跑大模型?
  • 手机上网可以固定ip地址吗?详细解析
  • Ubuntu22.04 安装 Miniconda3
  • python直方图
  • 【前端并发请求控制:必要性与实现策略】
  • 为何选择Spring框架学习设计模式与编码技巧?
  • 从“remote rejected”看git角色区别,Maintainer和Devoloper
  • 使用 Docker Compose 安装 Redis 7.2.4
  • Python基于PCA、PCA-kernel、LDA的同心圆数据降维项目实战
  • 2005-2022全国及各省家庭承包耕地流转总面积及经营耕地面积数据(无缺失)
  • 移动网页调试的多元路径:WebDebugX 与其他调试工具的组合使用策略
  • HarmonyOS Next 弹窗系列教程(2)
  • matlab实现掺杂光纤放大器的模拟
  • uniapp开发使用vue3组合式api,实现从vue模块中自动导入
  • Flotherm软件许可与硬件要求
  • 我的技术笔记
  • 《汇编语言》第14章 端口