SpringCloudAlibaba-Seata白话文入门简单介绍

📅 2026/7/15 20:14:19
SpringCloudAlibaba-Seata白话文入门简单介绍
一、问题场景问题场景在Spring Cloud Alibaba的微服务框架下不同服务模块之间接口调用是通过nacosopenfeign等组件实现使用openfeign组件实现A服务调用B服务接口其本质简单来说就是一次A服务对B服务发起的一次http请求这就产生一个问题当B服务接口执行成功后A服务继续往下执行产生报错此时A服务会回滚但是B服务已经执行成功并提交事务无法回滚而且B服务也无法知道A服务产生报错解决思路上面的场景就是一个简单的分布式事务问题若要解决该问题就需要一个既然管理A服务也能管理B服务的中间件因此seata就诞生了二、Seata介绍Seata 的设计思路是将一个分布式事务可以理解成一个全局事务下面挂了若干个分支事务而一个分支事务是一个满足 ACID 的本地事务因此我们可以操作分布式事务像操作本地事务一样。Seata 内部定义了 3个模块来处理全局事务和分支事务的关系和处理过程这三个组件分别是Transaction Coordinator (TC) 事务协调器维护全局事务的运行状态负责协调并驱动全局事务的提交或回滚。Transaction Manager (TM) 控制全局事务的边界负责开启一个全局事务并最终发起全局提交或全局回滚的决议。Resource Manager (RM) 控制分支事务负责分支注册、状态汇报并接收事务协调器的指令驱动分支本地事务的提交和回滚。全局事务的执行步骤TM 向 TC 申请开启一个全局事务TC 创建全局事务后返回全局唯一的 XIDXID 会在全局事务的上下文中传播RM 向 TC 注册分支事务该分支事务归属于拥有相同 XID 的全局事务TM 向 TC 发起全局提交或回滚TC 调度 XID 下的分支事务完成提交或者回滚。简单总结A服务调用B服务A服务就是全局事务发起者因此A服务TMRMB服务RM独立部署的seataTC。三、疑问解答1、XID如何在A服务B服务之间传递?服务发起方A服务Seata会通过请求拦截器RequestInterceptor自动从当前线程的RootContext中获取XID并将其添加到OpenFeign请求的HTTP Header中。这个Header的默认键名通常是X-SEATA-XID。服务提供方B服务Seata会通过Spring MVC拦截器HandlerInterceptor自动从接收到的HTTP Header中解析出XID并绑定到当前线程的RootContext中。2、在AT模式下需要需要在数据库创建undo_log表 A服务、B服务什么时候写入undo_log?Seata 拦截 SQLSeata 拦截到要执行的业务 SQL。查询“前镜像” (Before Image)在执行业务 SQL之前Seata 会先查询出将被修改的数据的原始状态这就是“前镜像”。对于INSERT操作前镜像为空。对于DELETE或UPDATE操作前镜像就是被删除或更新前的数据。执行业务 SQL真正执行你编写的业务 SQL例如更新库存。查询“后镜像” (After Image)在业务 SQL 执行之后Seata 会再次查询被修改的数据记录下修改后的状态这就是“后镜像”。对于DELETE操作后镜像为空。对于INSERT或UPDATE操作后镜像就是新插入或更新后的数据。生成并保存undo_logSeata 将“前镜像”和“后镜像”以及相关的 SQL 信息组合成一条回滚日志记录准备插入到undo_log表中。在同一本地事务中提交最关键的一步来了。Seata 会将“业务数据的修改”和“undo_log表的插入”这两个操作放在同一个本地数据库事务中提交。这意味着业务数据修改成功undo_log也一定会成功记录反之如果业务数据修改失败整个本地事务回滚undo_log的插入也会被撤销。总结来说A 服务和 B 服务在每个写操作INSERT/UPDATE/DELETE执行时都会独立、自动地完成这一系列操作。它们各自undo_log的写入是与其本地业务事务绑定在一起的。3、在AT模式下A服务B服务分别如何实现本地事务提交全局事务提交回滚一阶段本地事务提交A和B各自执行自己的SQL立即提交本地事务此时数据已真正落库。二阶段全局提交或回滚根据A服务TM的最终决定TC协调所有RMA和B执行清理undo_log提交或补偿回滚回滚。4、如何另一个服务并没有引入seata咋办方案核心思想侵入性数据一致性适用场景1. 升级为TCC模式业务层面手动预留资源、确认、取消高(需实现3个接口)强一致性核心业务对一致性要求极高2. 采用Saga模式定义正向操作和补偿操作失败后反向补偿中(需定义补偿逻辑)最终一致性长事务涉及多个服务或遗留系统3. 本地消息表消息队列A服务本地事务完成后发消息B服务消费消息低最终一致性通用方案对实时性要求不高的场景4. 业务层面手动补偿手工编写代码来处理失败的回滚高最终一致性非常特殊不适合常规业务