Seata AT模式如何实现分布式事务的原理和步骤?

摘要:Seata 本质是把分布式事务的各种经典方案(2PC、TCC、Saga、XA)做了极致封装和优化的框架,不用你从零写底层逻辑,只需要简单配置和少量注解,就能落地分布式事务。 它的核心设计是拆分全局事务为多个本地事务,由Seata统一协调管理
Seata 本质是把分布式事务的各种经典方案(2PC、TCC、Saga、XA)做了极致封装和优化的框架,不用你从零写底层逻辑,只需要简单配置和少量注解,就能落地分布式事务。 它的核心设计是拆分全局事务为多个本地事务,由Seata统一协调管理,保证这些本地事务要么全提交、要么全回滚;而且Seata对Java微服务(Spring Cloud/Dubbo)的侵入性极低,这也是它成为中小企业首选的关键。 先讲Seata的3个核心角色(大白话比喻,理解了角色才能懂流程),这是所有模式的基础,记牢这3个,后面的逻辑一眼就能看透: Seata三大核心角色(必懂) TC(Transaction Coordinator):事务协调者 → 全场总指挥 独立的Seata服务端(需要单独部署),负责创建/管理全局事务、分配全局事务ID(XID),协调所有参与者的提交/回滚,是整个分布式事务的“大脑”。 TM(Transaction Manager):事务管理器 → 事务发起者 就是你的业务入口服务(比如电商下单的「订单服务」),负责向TC开启全局事务,并最终向TC发起「全局提交」或「全局回滚」的请求。 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模式必须满足) 数据库支持本地事务(MySQL/Oracle/PG等主流数据库都满足); 数据库支持行级锁(InnoDB引擎,这是MySQL的默认引擎); 必须使用Seata提供的数据源代理(Seata要拦截SQL,生成undo log,自动代理,不用手动改)。 AT模式核心流程(分2个阶段,结合「电商下单」场景:订单服务(TM)+ 库存服务(RM)) 全程围绕XID关联,TC全程协调,先上大白话流程,再讲关键细节: 场景铺垫 TM:订单服务(下单接口加@GlobalTransactional注解,发起全局事务); RM1:订单服务的数据库(插入订单记录,分支事务1); RM2:库存服务的数据库(扣减库存,分支事务2); TC:Seata服务端(总指挥)。 第一阶段:本地事务提交(核心:做真实操作+留“后悔药”) 这是AT模式最关键的一步,所有RM都会执行本地事务并提交,同时生成undo log(后悔药),并向TC注册分支事务,流程如下: TM向TC发起「开启全局事务」请求,TC生成全局唯一XID并返回给TM; XID随微服务调用链透传(Seata自动做,比如Feign/Dubbo调用时,XID会放在请求头里),所有参与的RM都能拿到XID; 订单服务(RM1)执行本地操作:执行insert 订单SQL,Seata的数据源代理会拦截这个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。
阅读全文