SpringCloud Alibaba 之分布式全局事务 Seata 原理分析

1. 什么是 Seata?为什么需要它?

想象一下,你去银行转账:

  • 操作1:从你的账户扣款 1000 元
  • 操作2:向对方账户增加 1000 元

如果 操作1 成功,但 操作2 失败了,你的钱就凭空消失了!这就是典型的分布式事务问题

在微服务架构中,不同服务可能在不同的数据库上操作,如何保证多个服务的操作要么全部成功,要么全部失败?Seata(Simple Extensible Autonomous Transaction Architecture) 就是为了解决这个问题而生的。

2. Seata 的核心概念(先理解,再读源码)

Seata 的核心思想是 "两阶段提交(2PC)",但比传统 2PC 更轻量级。它的核心角色有:

  1. TC(Transaction Coordinator):事务协调者,负责全局事务的提交或回滚(Seata-Server)。
  2. TM(Transaction Manager):事务管理者(通常是业务入口方法),负责开启/提交/回滚全局事务。
  3. RM(Resource Manager):资源管理者(各个微服务),负责管理本地事务,并向 TC 汇报状态。

举个栗子🌰

  • TM 是银行柜员,负责发起转账事务。
  • RM1 是你的账户服务,RM2 是对方账户服务。
  • TC 是银行总部,决定最终是转账成功还是回滚。

3. Seata 的工作流程(源码核心逻辑)

Seata 的全局事务分为两个阶段:

阶段1:执行本地事务(RM 干活)

  1. TMTC 申请开启全局事务(GlobalBeginRequest)。
  2. TC 生成全局事务 ID(XID),并返回给 TM
  3. TM 调用 RM1 (你的账户扣款),RM1 执行本地事务,但不提交 ,而是记录 undo_log(用于回滚)。
  4. RM1TC 注册分支事务,并汇报状态(BranchRegisterRequest)。
  5. TM 调用 RM2 (对方账户加钱),同样记录 undo_log,但不提交。
  6. RM2 也向 TC 注册分支事务。

👉 核心源码

  • GlobalTransactionScanner(TM 入口)
  • DefaultCoordinator(TC 处理事务注册)
  • DataSourceProxy(RM 代理数据源,拦截 SQL 生成 undo_log)

阶段2:全局提交或回滚(TC 决策)

  • 如果所有 RM 都成功
    • TC 发送 GlobalCommitRequest,RM 提交本地事务。
  • 如果有 RM 失败
    • TC 发送 GlobalRollbackRequest,RM 根据 undo_log 回滚数据。

👉 核心源码

  • DefaultCore(TC 决策逻辑)
  • AsyncWorker(异步执行提交/回滚)
  • UndoLogManager(RM 回滚时解析 undo_log 恢复数据)

4. Seata 如何保证数据一致性?(关键设计)

(1)undo_log 机制(回滚的关键)

  • 在阶段1,RM 会记录修改前的数据快照(undo_log)。
  • 如果 TC 通知回滚,RM 会根据 undo_log 恢复数据。

源码关键类UndoLogManager

(2)AT 模式(默认模式,自动补偿)

  • 自动生成反向 SQL (如 UPDATE account SET money = money - 100 的回滚 SQL 是 UPDATE account SET money = money + 100)。
  • 依赖数据库本地事务 ,确保 undo_log 和业务 SQL 在同一个事务里。

源码关键类SQLVisitorFactory(解析 SQL 生成回滚语句)

(3)全局锁(防止脏写)

  • 在阶段1,RM 会申请全局锁,防止其他事务修改相同数据。
  • 如果拿不到锁,事务会失败,避免数据不一致。

源码关键类GlobalLockTemplate

5. 总结(Seata 的优缺点)

优点

对业务代码侵入小 (只需加 @GlobalTransactional 注解)。

支持多种模式 (AT、TCC、SAGA、XA)。

高性能(相比传统 2PC,减少了阻塞时间)。

缺点

依赖 TC(Seata-Server) ,TC 单点故障会影响整个系统(可集群部署)。

AT 模式有幻读问题(高并发场景下可能读到中间状态)。

6. 进阶思考(如何优化 Seata?)

  • TC 高可用:部署 Seata-Server 集群 + 数据库 HA。
  • 混合模式:核心业务用 TCC(更强一致性),普通业务用 AT(更高性能)。
  • 结合消息队列:用 RocketMQ 事务消息做最终一致性补偿。

🚀 现在,你对 Seata 的源码是不是有了清晰的认识?
💡 动手实践: 搭建一个 Seata Demo,Debug 跟踪 XID 传递和 undo_log 生成,理解会更深刻!

如果有疑问,欢迎留言讨论!🎯

推荐阅读文章

相关推荐
摇滚侠6 小时前
SpringMVC 入门到实战 文件上传 75-77
java·后端·spring·maven·intellij-idea
小熊美家熊猫系统9 小时前
电子合同技术实现与合规实践
java·开发语言·分布式
AI 小老六11 小时前
Google AX 控制面拆解:分布式 Agent 如何把断点恢复、审计策略和执行调度收进同一条链路
人工智能·分布式·后端·ai·架构·ai编程
functionflux12 小时前
kafka-python:Python 生态中最成熟的 Kafka 客户端
分布式·python·其他·kafka
迦蓝叶12 小时前
【开源自荐】JAiRouter:一个轻量级 AI 模型服务网关的开源实践
java·人工智能·spring·开源·llm-gateway·mass
慕木沐12 小时前
【Spring AI + Google ADK 】流式输出时 outputKey 状态缓存失败的问题
人工智能·spring·缓存
雪宫街道13 小时前
SpringBoot 向 IOC 容器注册组件的两种姿势:@Configuration 与 @Import
java·spring boot·后端·spring
sou_time14 小时前
从 0 到 商用:AI Agent x SKILL x MCP 全栈实战教程:L2 高等篇:MCP 协议 + Spring AI + Agent 编排
java·人工智能·spring
_Aaron___15 小时前
MyBatis 动态排序别乱用 ${}:ORDER BY 的安全写法
java·spring·mybatis