Seata实现分布式事务:大白话全剖析(核心讲透AT模式)

📅 发布时间:2026/7/7 23:51:26 👁️ 浏览次数:
Seata实现分布式事务:大白话全剖析(核心讲透AT模式)
Seata 本质是把分布式事务的各种经典方案2PC、TCC、Saga、XA做了极致封装和优化的框架不用你从零写底层逻辑只需要简单配置和少量注解就能落地分布式事务。它的核心设计是拆分全局事务为多个本地事务由Seata统一协调管理保证这些本地事务要么全提交、要么全回滚而且Seata对Java微服务Spring Cloud/Dubbo的侵入性极低这也是它成为中小企业首选的关键。先讲Seata的3个核心角色大白话比喻理解了角色才能懂流程这是所有模式的基础记牢这3个后面的逻辑一眼就能看透Seata三大核心角色必懂TCTransaction Coordinator事务协调者→ 全场总指挥独立的Seata服务端需要单独部署负责创建/管理全局事务、分配全局事务IDXID协调所有参与者的提交/回滚是整个分布式事务的“大脑”。TMTransaction Manager事务管理器→ 事务发起者就是你的业务入口服务比如电商下单的「订单服务」负责向TC开启全局事务并最终向TC发起「全局提交」或「全局回滚」的请求。RMResource Manager资源管理器→ 事务参与者所有涉及数据操作的服务/数据库比如下单场景的「库存服务」「支付服务」负责管理本地事务向TC注册分支事务每个RM的本地事务都是一个「分支事务」并接收TC的指令执行本地事务的提交/回滚。核心关联一个全局事务 1个TM发起 1个TC协调 N个RM参与N个分支事务所有操作都通过全局唯一的XID关联XID是分布式事务的“身份证”微服务调用链中必须透传XIDSeata会自动做这件事。重点Seata最常用的AT模式自动事务90%场景用它Seata支持AT、TCC、Saga、XA四种模式其中AT模式是默认、最主流的也是最贴合日常开发的——几乎无业务侵入只加一个注解、性能接近本地事务、自动完成回滚补偿完美适配互联网高并发场景下面用大白话讲透它的实现原理核心是改进版的2PC解决了原生2PC性能差、锁资源久的问题。先给AT模式定调基于本地事务undo log的自动两阶段提交核心创新是第一阶段就执行本地事务并提交释放数据库锁第二阶段只做“确认”或“回滚补偿”彻底解决了原生2PC的性能瓶颈。前置条件AT模式必须满足数据库支持本地事务MySQL/Oracle/PG等主流数据库都满足数据库支持行级锁InnoDB引擎这是MySQL的默认引擎必须使用Seata提供的数据源代理Seata要拦截SQL生成undo log自动代理不用手动改。AT模式核心流程分2个阶段结合「电商下单」场景订单服务TM 库存服务RM全程围绕XID关联TC全程协调先上大白话流程再讲关键细节场景铺垫TM订单服务下单接口加GlobalTransactional注解发起全局事务RM1订单服务的数据库插入订单记录分支事务1RM2库存服务的数据库扣减库存分支事务2TCSeata服务端总指挥。第一阶段本地事务提交核心做真实操作留“后悔药”这是AT模式最关键的一步所有RM都会执行本地事务并提交同时生成undo log后悔药并向TC注册分支事务流程如下TM向TC发起「开启全局事务」请求TC生成全局唯一XID并返回给TMXID随微服务调用链透传Seata自动做比如Feign/Dubbo调用时XID会放在请求头里所有参与的RM都能拿到XID订单服务RM1执行本地操作执行insert 订单SQLSeata的数据源代理会拦截这个SQL做3件事「前置快照」执行SQL前先查询要操作的数据保存数据快照比如订单表的初始状态无订单「执行SQL」真正插入订单记录完成业务操作「生成undo log」把前置快照当前数据SQL类型插入/更新/删除封装成undo log写入数据库的undo_log表Seata自动创建这就是“后悔药”RM1提交本地事务并立即释放数据库的行级锁原生2PC的致命问题就是不提交、不释放锁AT模式这里直接提交性能拉满RM1向TC注册「订单分支事务」告知TC我这步操作完成了留了undo log随时可以回滚库存服务RM2收到带XID的调用请求重复步骤3-5扣减库存→生成undo log→提交本地事务→注册库存分支事务到TC。第一阶段结束所有RM的本地事务都已提交数据已经变更锁全部释放业务无感知如果其中任何一个RM执行失败比如库存不足直接回滚自己的本地事务TM感知到后向TC发起「全局回滚」。第二阶段全局提交 OR 全局回滚TC总指挥只做轻量操作第一阶段所有RM都成功后TM会向TC发起「全局提交」请求如果有任何一个RM失败TM发起「全局回滚」请求TC根据请求指令向所有RM下发统一命令。情况1全局提交最常见轻量到几乎无开销TC向所有RM订单RM、库存RM下发「全局提交」指令各RM收到指令后只做一件事异步删除自己的undo log后悔药没用了删掉占空间RM向TC反馈“提交完成”所有RM反馈后TC标记全局事务完成。为什么这么轻量因为第一阶段已经完成了真实的业务操作并提交第二阶段的提交只是“清理垃圾”没有任何数据库锁竞争性能几乎无损耗。情况2全局回滚有错误吃“后悔药”恢复数据这是AT模式的核心补偿逻辑通过undo log自动回滚数据全程无需业务代码介入流程如下TC向所有RM下发「全局回滚」指令并附带要回滚的分支事务ID各RM收到指令后开启本地小事务执行回滚操作从undo_log表中根据分支ID查询对应的undo log前置快照当前数据数据校验对比undo log中的「当前数据」和数据库中真实的「当前数据」确保数据没被其他事务修改Seata的乐观锁机制避免脏回滚恢复数据用undo log中的「前置快照」覆盖数据库的当前数据比如订单RM删除插入的订单记录库存RM恢复扣减的库存删除undo log回滚完成后删除该条undo logRM提交这个本地回滚事务向TC反馈“回滚完成”所有RM回滚完成后TC标记全局事务回滚成功。关键回滚操作是基于本地事务的快速且无锁竞争即使个别RM回滚失败Seata会自动重试直到成功保证最终回滚。AT模式的核心优势为什么是90%场景的首选几乎无业务侵入只需要在事务入口加GlobalTransactional注解业务代码一行不用改开发成本极低性能极高第一阶段就提交本地事务、释放锁解决了原生2PC的性能瓶颈接近本地事务的性能自动回滚补偿基于undo log自动完成回滚不用像TCC那样手动写补偿代码适配高并发无长期锁、轻量提交完美适配互联网电商、支付等高并发场景。Seata其他模式的实现简单讲按需选择Seata封装了所有经典分布式事务方案除了AT模式其他模式都是为了适配特殊场景核心是Seata帮你处理了底层的协调、重试、幂等、事务上下文传递你只需要按规范写少量代码不用从零开发。1. Seata TCC模式适配强一致高并发需手动写代码完全遵循TCC的Try-Confirm-Cancel三步但Seata做了封装你只需要为每个业务写3个方法分别加Tcc主方法、Confirm确认方法、Cancel取消方法注解Seata自动管理事务上下文XID协调各服务的Try/Confirm/Cancel执行自动处理幂等、空补偿、悬挂TCC的三大坑不用自己写判断逻辑。适用场景AT模式无法覆盖的场景比如非数据库操作调用第三方支付接口、扣减缓存库存。2. Seata Saga模式适配长事务复杂流程低代码专为长流程、多步骤的分布式事务设计Seata做了两大优化普通Saga你写每个步骤的执行方法和补偿方法Seata按顺序执行失败则倒序执行补偿状态机Saga用JSON/YAML定义事务流程步骤顺序、分支、重试规则不用写代码低代码配置支持复杂的流程比如分支、并行、条件判断。适用场景跨境支付、供应链结算、保险理赔等长流程业务步骤多、耗时久甚至跨天。3. Seata XA模式原生2PC强一致性能差完全实现数据库的XA协议原生2PCSeata作为协调者管理各数据库的XA事务第一阶段各数据库执行XA prepare预提交锁定资源第二阶段TC下发XA commit/rollback各数据库执行正式提交/回滚。特点强一致性数据库层面保证但性能差、资源锁定久仅适用于对一致性要求极高的低并发场景比如银行核心交易。Seata实现分布式事务的核心亮点总结Seata之所以能成为Java微服务分布式事务的首选核心是它解决了传统分布式事务方案的痛点做了极致的工程化优化统一协调通过TC/TM/RM三大角色把分布式事务拆分为“全局事务分支事务”统一协调管理逻辑清晰极简开发主流的AT模式几乎无侵入只加一个注解开发成本接近本地事务性能优化AT模式的“第一阶段提交undo log回滚”彻底解决了原生2PC的性能瓶颈适配高并发全场景覆盖封装AT/TCC/Saga/XA四种模式从高并发到长事务从无侵入到手动开发满足所有分布式事务场景自动避坑内置幂等、重试、空补偿、悬挂、脏回滚等机制不用开发者手动处理分布式事务的各种坑无缝集成完美适配Spring Boot/Spring Cloud/Dubbo支持MySQL/Oracle/PG等主流数据库配置简单快速落地。最简落地Seata AT模式代码层面让你有直观认知不用复杂配置只看核心代码就能知道Seata有多简单Spring Cloud场景1. 入口服务TM事务发起者只需要在业务入口方法上加GlobalTransactional注解就是TM开启全局事务/* by yours.tools - online tools website : yours.tools/zh/regexdso.html */ RestController public class OrderController { Autowired private OrderService orderService; Autowired private StockFeignClient stockFeignClient; // 调用库存服务的Feign客户端 // 下单接口分布式事务入口TM GlobalTransactional(rollbackFor Exception.class) // 加这个注解就够了 PostMapping(/createOrder) public String createOrder(RequestParam Long goodsId, RequestParam Integer num) { // 1. 本地操作创建订单RM1订单服务的本地事务 orderService.createOrder(goodsId, num); // 2. 调用库存服务扣减库存RM2库存服务的本地事务XID自动透传 Boolean reduceResult stockFeignClient.reduceStock(goodsId, num); if (!reduceResult) { throw new RuntimeException(库存扣减失败全局回滚); } return 下单成功; } }2. 参与服务RM库存服务一行注解都不用加正常写本地业务代码就行Seata自动拦截并生成undo log/* by yours.tools - online tools website : yours.tools/zh/regexdso.html */ RestController public class StockController { Autowired private StockService stockService; // 扣减库存RM普通本地接口 PostMapping(/reduceStock) public Boolean reduceStock(RequestParam Long goodsId, RequestParam Integer num) { stockService.reduceStock(goodsId, num); // 正常扣减库存的本地方法 return true; } }这就是Seata的威力业务代码几乎无改动只加一个注解就能实现分布式事务的“要么全成、要么全错”。核心总结Seata的核心是拆分全局事务为多个本地事务通过TC总指挥、TM发起者、RM参与者三大角色协调用XID关联整个调用链主流的AT模式是改进版2PC核心是「第一阶段本地提交生成undo log第二阶段轻量提交/基于undo log自动回滚」无侵入、高性能适配90%的互联网场景Seata封装了TCC/Saga/XA模式分别适配强一致高并发、长流程复杂业务、强一致低并发场景底层自动处理幂等、重试等分布式坑落地极简单AT模式只需要在事务入口加GlobalTransactional注解业务代码无改动完美集成Spring Cloud/Dubbo。❤️ 如果你喜欢这篇文章请点赞支持 同时欢迎关注我的博客获取更多精彩内容本文来自博客园作者佛祖让我来巡山转载请注明原文链接https://www.cnblogs.com/sun-10387834/p/19584278