1. 什么是 Seata?为什么需要它?
想象一下,你去银行转账:
- 操作1:从你的账户扣款 1000 元
- 操作2:向对方账户增加 1000 元
如果 操作1 成功,但 操作2 失败了,你的钱就凭空消失了!这就是典型的分布式事务问题。
在微服务架构中,不同服务可能在不同的数据库上操作,如何保证多个服务的操作要么全部成功,要么全部失败?Seata(Simple Extensible Autonomous Transaction Architecture) 就是为了解决这个问题而生的。
2. Seata 的核心概念(先理解,再读源码)
Seata 的核心思想是 "两阶段提交(2PC)",但比传统 2PC 更轻量级。它的核心角色有:
- TC(Transaction Coordinator):事务协调者,负责全局事务的提交或回滚(Seata-Server)。
- TM(Transaction Manager):事务管理者(通常是业务入口方法),负责开启/提交/回滚全局事务。
- RM(Resource Manager):资源管理者(各个微服务),负责管理本地事务,并向 TC 汇报状态。
举个栗子🌰:
- TM 是银行柜员,负责发起转账事务。
- RM1 是你的账户服务,RM2 是对方账户服务。
- TC 是银行总部,决定最终是转账成功还是回滚。
3. Seata 的工作流程(源码核心逻辑)
Seata 的全局事务分为两个阶段:
阶段1:执行本地事务(RM 干活)
- TM 向 TC 申请开启全局事务(
GlobalBeginRequest
)。 - TC 生成全局事务 ID(XID),并返回给 TM。
- TM 调用 RM1 (你的账户扣款),RM1 执行本地事务,但不提交 ,而是记录 undo_log(用于回滚)。
- RM1 向 TC 注册分支事务,并汇报状态(
BranchRegisterRequest
)。 - TM 调用 RM2 (对方账户加钱),同样记录 undo_log,但不提交。
- RM2 也向 TC 注册分支事务。
👉 核心源码:
GlobalTransactionScanner
(TM 入口)DefaultCoordinator
(TC 处理事务注册)DataSourceProxy
(RM 代理数据源,拦截 SQL 生成 undo_log)
阶段2:全局提交或回滚(TC 决策)
- 如果所有 RM 都成功 :
- TC 发送
GlobalCommitRequest
,RM 提交本地事务。
- TC 发送
- 如果有 RM 失败 :
- TC 发送
GlobalRollbackRequest
,RM 根据 undo_log 回滚数据。
- TC 发送
👉 核心源码:
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 生成,理解会更深刻!
如果有疑问,欢迎留言讨论!🎯