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

Seata 本质是把分布式事务的各种经典方案(2PC、TCC、Saga、XA)做了极致封装和优化的框架,不用你从零写底层逻辑,只需要简单配置和少量注解,就能落地分布式事务。

它的核心设计是拆分全局事务为多个本地事务,由Seata统一协调管理,保证这些本地事务要么全提交、要么全回滚;而且Seata对Java微服务(Spring Cloud/Dubbo)的侵入性极低,这也是它成为中小企业首选的关键。

先讲Seata的3个核心角色(大白话比喻,理解了角色才能懂流程),这是所有模式的基础,记牢这3个,后面的逻辑一眼就能看透:

Seata三大核心角色(必懂)

  1. TC(Transaction Coordinator):事务协调者 → 全场总指挥
    独立的Seata服务端(需要单独部署),负责创建/管理全局事务、分配全局事务ID(XID),协调所有参与者的提交/回滚,是整个分布式事务的"大脑"。
  2. TM(Transaction Manager):事务管理器 → 事务发起者
    就是你的业务入口服务 (比如电商下单的「订单服务」),负责向TC开启全局事务,并最终向TC发起「全局提交」或「全局回滚」的请求。
  3. RM(Resource Manager):资源管理器 → 事务参与者
    所有涉及数据操作的服务/数据库(比如下单场景的「库存服务」「支付服务」),负责管理本地事务,向TC注册分支事务(每个RM的本地事务都是一个「分支事务」),并接收TC的指令,执行本地事务的提交/回滚。

核心关联 :一个全局事务 = 1个TM发起 + 1个TC协调 + N个RM参与(N个分支事务),所有操作都通过全局唯一的XID关联(XID是分布式事务的"身份证",微服务调用链中必须透传XID,Seata会自动做这件事)。


重点:Seata最常用的AT模式(自动事务,90%场景用它)

Seata支持AT、TCC、Saga、XA四种模式,其中AT模式是默认、最主流的 ,也是最贴合日常开发的------几乎无业务侵入 (只加一个注解)、性能接近本地事务自动完成回滚补偿 ,完美适配互联网高并发场景,下面用大白话讲透它的实现原理(核心是改进版的2PC,解决了原生2PC性能差、锁资源久的问题)。

先给AT模式定调:基于本地事务+undo log的自动两阶段提交 ,核心创新是第一阶段就执行本地事务并提交,释放数据库锁,第二阶段只做"确认"或"回滚补偿",彻底解决了原生2PC的性能瓶颈。

前置条件(AT模式必须满足)

  1. 数据库支持本地事务(MySQL/Oracle/PG等主流数据库都满足);
  2. 数据库支持行级锁(InnoDB引擎,这是MySQL的默认引擎);
  3. 必须使用Seata提供的数据源代理(Seata要拦截SQL,生成undo log,自动代理,不用手动改)。

AT模式核心流程(分2个阶段,结合「电商下单」场景:订单服务(TM)+ 库存服务(RM))

全程围绕XID关联,TC全程协调,先上大白话流程,再讲关键细节:

场景铺垫

  • TM:订单服务(下单接口加@GlobalTransactional注解,发起全局事务);
  • RM1:订单服务的数据库(插入订单记录,分支事务1);
  • RM2:库存服务的数据库(扣减库存,分支事务2);
  • TC:Seata服务端(总指挥)。

第一阶段:本地事务提交(核心:做真实操作+留"后悔药")

这是AT模式最关键的一步,所有RM都会执行本地事务并提交 ,同时生成undo log(后悔药),并向TC注册分支事务,流程如下:

  1. TM向TC发起「开启全局事务」请求,TC生成全局唯一XID并返回给TM;
  2. XID随微服务调用链透传(Seata自动做,比如Feign/Dubbo调用时,XID会放在请求头里),所有参与的RM都能拿到XID;
  3. 订单服务(RM1)执行本地操作 :执行insert 订单SQL,Seata的数据源代理会拦截这个SQL,做3件事:
    • 「前置快照」:执行SQL前,先查询要操作的数据,保存数据快照(比如订单表的初始状态:无订单);
    • 「执行SQL」:真正插入订单记录,完成业务操作;
    • 「生成undo log」:把前置快照+当前数据+SQL类型 (插入/更新/删除)封装成undo log,写入数据库的undo_log表(Seata自动创建),这就是"后悔药";
  4. RM1提交本地事务,并立即释放数据库的行级锁(原生2PC的致命问题就是不提交、不释放锁,AT模式这里直接提交,性能拉满);
  5. RM1向TC注册「订单分支事务」,告知TC:我这步操作完成了,留了undo log,随时可以回滚;
  6. 库存服务(RM2)收到带XID的调用请求,重复步骤3-5:扣减库存→生成undo log→提交本地事务→注册库存分支事务到TC。

第一阶段结束:所有RM的本地事务都已提交,数据已经变更,锁全部释放,业务无感知;如果其中任何一个RM执行失败(比如库存不足),直接回滚自己的本地事务,TM感知到后向TC发起「全局回滚」。

第二阶段:全局提交 OR 全局回滚(TC总指挥,只做轻量操作)

第一阶段所有RM都成功后,TM会向TC发起「全局提交」请求;如果有任何一个RM失败,TM发起「全局回滚」请求,TC根据请求指令,向所有RM下发统一命令。

情况1:全局提交(最常见,轻量到几乎无开销)

  1. TC向所有RM(订单RM、库存RM)下发「全局提交」指令;
  2. 各RM收到指令后,只做一件事:异步删除自己的undo log(后悔药没用了,删掉占空间);
  3. RM向TC反馈"提交完成",所有RM反馈后,TC标记全局事务完成

为什么这么轻量? 因为第一阶段已经完成了真实的业务操作并提交,第二阶段的提交只是"清理垃圾",没有任何数据库锁竞争,性能几乎无损耗。

情况2:全局回滚(有错误,吃"后悔药"恢复数据)

这是AT模式的核心补偿逻辑,通过undo log自动回滚数据,全程无需业务代码介入,流程如下:

  1. TC向所有RM下发「全局回滚」指令,并附带要回滚的分支事务ID;
  2. 各RM收到指令后,开启本地小事务 ,执行回滚操作:
    • 从undo_log表中根据分支ID查询对应的undo log(前置快照+当前数据);
    • 数据校验:对比undo log中的「当前数据」和数据库中真实的「当前数据」,确保数据没被其他事务修改(Seata的乐观锁机制,避免脏回滚);
    • 恢复数据:用undo log中的「前置快照」覆盖数据库的当前数据(比如订单RM删除插入的订单记录,库存RM恢复扣减的库存);
    • 删除undo log:回滚完成后,删除该条undo log;
  3. RM提交这个本地回滚事务,向TC反馈"回滚完成";
  4. 所有RM回滚完成后,TC标记全局事务回滚成功

关键 :回滚操作是基于本地事务的,快速且无锁竞争,即使个别RM回滚失败,Seata会自动重试,直到成功(保证最终回滚)。

AT模式的核心优势(为什么是90%场景的首选)

  1. 几乎无业务侵入 :只需要在事务入口加@GlobalTransactional注解,业务代码一行不用改,开发成本极低;
  2. 性能极高:第一阶段就提交本地事务、释放锁,解决了原生2PC的性能瓶颈,接近本地事务的性能;
  3. 自动回滚补偿:基于undo log自动完成回滚,不用像TCC那样手动写补偿代码;
  4. 适配高并发:无长期锁、轻量提交,完美适配互联网电商、支付等高并发场景。

Seata其他模式的实现(简单讲,按需选择)

Seata封装了所有经典分布式事务方案,除了AT模式,其他模式都是为了适配特殊场景,核心是Seata帮你处理了底层的协调、重试、幂等、事务上下文传递,你只需要按规范写少量代码,不用从零开发。

1. Seata TCC模式(适配强一致+高并发,需手动写代码)

完全遵循TCC的Try-Confirm-Cancel三步,但Seata做了封装:

  1. 你只需要为每个业务写3个方法,分别加@Tcc(主方法)、@Confirm(确认方法)、@Cancel(取消方法)注解;
  2. Seata自动管理事务上下文(XID),协调各服务的Try/Confirm/Cancel执行;
  3. 自动处理幂等、空补偿、悬挂(TCC的三大坑),不用自己写判断逻辑。

适用场景:AT模式无法覆盖的场景(比如非数据库操作:调用第三方支付接口、扣减缓存库存)。

2. Seata Saga模式(适配长事务+复杂流程,低代码)

专为长流程、多步骤的分布式事务设计,Seata做了两大优化:

  1. 普通Saga:你写每个步骤的执行方法和补偿方法,Seata按顺序执行,失败则倒序执行补偿;
  2. 状态机Saga :用JSON/YAML定义事务流程(步骤顺序、分支、重试规则),不用写代码,低代码配置,支持复杂的流程(比如分支、并行、条件判断)。

适用场景:跨境支付、供应链结算、保险理赔等长流程业务(步骤多、耗时久,甚至跨天)。

3. Seata XA模式(原生2PC,强一致,性能差)

完全实现数据库的XA协议(原生2PC),Seata作为协调者,管理各数据库的XA事务:

  1. 第一阶段:各数据库执行XA prepare(预提交),锁定资源;
  2. 第二阶段:TC下发XA commit/rollback,各数据库执行正式提交/回滚。

特点 :强一致性(数据库层面保证),但性能差、资源锁定久,仅适用于对一致性要求极高的低并发场景(比如银行核心交易)。


Seata实现分布式事务的核心亮点(总结)

Seata之所以能成为Java微服务分布式事务的首选,核心是它解决了传统分布式事务方案的痛点,做了极致的工程化优化:

  1. 统一协调:通过TC/TM/RM三大角色,把分布式事务拆分为"全局事务+分支事务",统一协调管理,逻辑清晰;
  2. 极简开发:主流的AT模式几乎无侵入,只加一个注解,开发成本接近本地事务;
  3. 性能优化:AT模式的"第一阶段提交+undo log回滚",彻底解决了原生2PC的性能瓶颈,适配高并发;
  4. 全场景覆盖:封装AT/TCC/Saga/XA四种模式,从高并发到长事务,从无侵入到手动开发,满足所有分布式事务场景;
  5. 自动避坑:内置幂等、重试、空补偿、悬挂、脏回滚等机制,不用开发者手动处理分布式事务的各种坑;
  6. 无缝集成:完美适配Spring Boot/Spring Cloud/Dubbo,支持MySQL/Oracle/PG等主流数据库,配置简单,快速落地。

最简落地Seata AT模式(代码层面,让你有直观认知)

不用复杂配置,只看核心代码,就能知道Seata有多简单(Spring Cloud场景):

1. 入口服务(TM,事务发起者)

只需要在业务入口方法 上加@GlobalTransactional注解,就是TM,开启全局事务:

java 复制代码
@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:

java 复制代码
@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的威力:业务代码几乎无改动,只加一个注解,就能实现分布式事务的"要么全成、要么全错"。


核心总结

  1. Seata的核心是拆分全局事务为多个本地事务 ,通过TC(总指挥)、TM(发起者)、RM(参与者)三大角色协调,用XID关联整个调用链;
  2. 主流的AT模式是改进版2PC,核心是「第一阶段本地提交+生成undo log,第二阶段轻量提交/基于undo log自动回滚」,无侵入、高性能,适配90%的互联网场景;
  3. Seata封装了TCC/Saga/XA模式,分别适配强一致高并发长流程复杂业务强一致低并发场景,底层自动处理幂等、重试等分布式坑;
  4. 落地极简单:AT模式只需要在事务入口加@GlobalTransactional注解,业务代码无改动,完美集成Spring Cloud/Dubbo。
相关推荐
编程彩机7 小时前
互联网大厂Java面试:从Spring Boot到分布式事务的技术场景解析
spring boot·kafka·分布式事务·微服务架构·java面试·技术解析
编程彩机3 天前
互联网大厂Java面试:从Spring Boot到微服务优化场景解析
spring boot·分布式事务·微服务架构·java面试·技术解析
编程彩机4 天前
互联网大厂Java面试:从分布式架构到大数据场景解析
java·大数据·微服务·spark·kafka·分布式事务·分布式架构
编程彩机4 天前
互联网大厂Java面试:从分布式事务到微服务优化的技术场景解读
java·spring boot·redis·微服务·面试·kafka·分布式事务
编程彩机4 天前
互联网大厂Java面试:从Spring WebFlux到分布式事务的技术场景解析
java·微服务·面试·分布式事务·spring webflux
编程彩机6 天前
互联网大厂Java面试:从Spring MVC到微服务架构场景解析
java·spring cloud·微服务·分布式事务·spring mvc
编程彩机7 天前
互联网大厂Java面试:从消息队列到微服务架构场景解析
kafka·消息队列·分布式事务·微服务架构·java面试
短剑重铸之日8 天前
《SpringCloud实用版》 Seata 分布式事务实战:AT / TCC / Saga /XA
后端·spring·spring cloud·seata·分布式事务
编程彩机8 天前
互联网大厂Java面试:从Spring Cloud到分布式事务的技术场景解析
java·spring cloud·微服务·消息队列·分布式事务