分布式事务 Seata?

2025年 阅读约 15 分钟 面试指南 · Spring Cloud

深入解析Seata分布式事务:AT模式(自动补偿)、TCC模式(两阶段补偿)、Saga模式(长事务)、XA模式、TC/TM/RM三大组件、全局锁与写隔离,附面试模拟问答。

一句话总结

Seata 是阿里巴巴开源的分布式事务解决方案,核心思想:全局事务 = 一组分支事务的集合,要么全部成功,要么全部回滚。三大组件:TC(Transaction Coordinator,事务协调者,独立部署)、TM(Transaction Manager,事务管理器,标注 @GlobalTransactional)、RM(Resource Manager,资源管理器,管理分支事务)。四种模式:AT(自动补偿,默认推荐)、TCC(两阶段补偿,性能好)、Saga(长事务,正向+补偿)、XA(强一致,性能差)。

初级理解

分布式事务问题

# 场景:下单流程 # 订单服务:创建订单 # 库存服务:扣减库存 # 账户服务:扣减余额 # 问题 # 订单创建成功 → 库存扣减成功 → 账户扣减失败 # 订单和库存需要回滚,但它们是不同服务、不同数据库 # 本地事务(@Transactional)无法跨服务回滚 # 解决方案:Seata 分布式事务 @GlobalTransactional // 全局事务注解 public void createOrder(OrderDTO dto) { orderService.create(dto); // 订单服务 stockService.deduct(dto); // 库存服务 accountService.deduct(dto); // 账户服务 // 任何一步失败,前面成功的步骤自动回滚 }

中级深入

AT 模式原理

# AT 模式(Automatic Transaction)两阶段 # 一阶段:执行 SQL,记录 undo_log # 1. 解析 SQL,获取 before-image(修改前数据) # 2. 执行业务 SQL # 3. 获取 after-image(修改后数据) # 4. 将 before-image 和 after-image 写入 undo_log 表 # 5. 提交本地事务(一阶段就提交!) # 二阶段-提交:全局事务成功 # 1. 异步删除 undo_log(清理) # 二阶段-回滚:全局事务失败 # 1. 读取 undo_log 中的 before-image # 2. 用 before-image 还原数据(反向 SQL) # 3. 删除 undo_log # 关键:一阶段就提交本地事务 # 优点:锁持有时间短,性能好 # 缺点:一阶段提交后数据对其他事务可见(脏读风险)

Seata 四大模式对比

模式一致性性能侵入性适用场景
AT最终一致通用场景(默认推荐)
TCC最终一致很高高(需写 try/confirm/cancel)高性能场景
Saga最终一致长事务、老系统
XA强一致强一致性要求

高级拓展

TCC 模式

# TCC(Try-Confirm-Cancel)模式 # Try:预留资源(检查+锁定) # Confirm:确认提交(使用预留资源) # Cancel:取消回滚(释放预留资源) # 示例:账户扣款 public interface AccountTccAction { // Try:冻结余额 @TwoPhaseBusinessAction(name = "deduct", commitMethod = "confirm", rollbackMethod = "cancel") boolean tryDeduct(BusinessActionContext ctx, @BusinessActionContextParameter("userId") Long userId, BigDecimal amount); // Confirm:扣减冻结余额 boolean confirm(BusinessActionContext ctx); // Cancel:解冻余额 boolean cancel(BusinessActionContext ctx); } # TCC 优点 # 1. 一阶段就释放锁(Try 只预留) # 2. 性能比 AT 更好 # 3. 不依赖数据库 undo_log # TCC 缺点 # 1. 代码侵入性强(每个接口写三个方法) # 2. 需要处理空回滚、悬挂、幂等

全局锁与写隔离

# AT 模式写隔离 # 问题:一阶段提交后,其他事务可能修改同一行数据 # 解决:全局锁 # 全局锁流程 # 1. 一阶段:获取本地锁 + 全局锁 # 2. 提交本地事务,释放本地锁,保留全局锁 # 3. 二阶段:释放全局锁 # 写隔离 # 事务 A 修改记录 X(持有全局锁) # 事务 B 也要修改记录 X # → B 需要等待 A 的全局锁释放 # → 如果 A 回滚,B 可以继续 # → 如果 A 提交,B 获取锁后执行

实战场景

场景:Seata AT 模式配置

# 1. 部署 Seata Server(TC) # 下载 seata-server,配置注册中心和存储模式 # 2. 每个服务引入依赖 <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> </dependency> # 3. 每个服务配置 seata: tx-service-group: my_tx_group # 事务分组 service: vgroup-mapping: my_tx_group: default # 映射到 Seata 集群 # 4. 每个数据库添加 undo_log 表 # CREATE TABLE undo_log (...) # 5. 业务方法添加 @GlobalTransactional @GlobalTransactional public void createOrder(OrderDTO dto) { }

面试模拟

面试官:Seata AT 模式的原理?

你:两阶段:一阶段执行 SQL 并记录 undo_log(before-image 和 after-image),然后提交本地事务;二阶段如果全局成功则删除 undo_log,如果失败则用 before-image 反向补偿。一阶段就提交,锁持有时间短,性能好。

面试官:AT 和 TCC 有什么区别?

你:AT 自动生成回滚 SQL,对业务无侵入,但依赖数据库 undo_log。TCC 需要手写 try/confirm/cancel 三个方法,侵入性强但性能更好,不依赖数据库。AT 适合通用场景,TCC 适合高性能场景。