Seata 原理与源码解析:分布式事务的终极解法 - 实践

在微服务架构中,一个完整的业务往往会拆分成多个服务调用。
比如「下单」 → 涉及订单服务、库存服务、支付服务,这时就会遇到一个难题:如何保证跨服务的一致性?
为了解决这个问题而生的。就是Seata 就
一、为什么需要 Seata?
传统单体应用里,事务依赖数据库的ACID 特性,MySQL 一条 BEGIN … COMMIT 就能搞定。
但在微服务里:
- 每个服务都有独立数据库
- 一个业务可能要跨 3-5 个库
- 分布式系统有网络延迟、失败风险
这时 本地事务就无能为力了,需要分布式事务协调器来保障全局一致性。
二、Seata 的核心思想
Seata 提供了一个全局事务管理器(TC:Transaction Coordinator),它通过拦截各个服务的本地事务,统一协调提交或回滚。
Seata 支持四种事务模式:
- AT 模式(最常用)
- 自动代理数据库操作
- 基于 两阶段提交(2PC) 实现:
- 一阶段保存快照并执行业务 SQL
- 二阶段提交则清理快照,回滚则用快照还原
- 适合大多数业务场景
- TCC 模式
- Try-Confirm-Cancel 三阶段事务
- 需要业务手写三个手段
- 灵活但开发成本高
- Saga 模式
- 长事务补偿模式
- 通过状态机和补偿动作保证一致性
- XA 模式
- 基于数据库 XA 协议
- 强一致性,但性能较差
三、Seata 架构图(竖向结构,避免过宽)
解读:
- TM:发起、结束全局事务(相当于老板)。
- RM:管理具体资源(数据库操控,像工人)。
- TC:协调大家一起干活(项目经理)。
四、Seata 的执行流程(AT 模式)
假设「下单」场景:订单服务 → 库存服务 → 支付服务。
- TM 向 TC发起全局事务
- 各服务 RM注册分支事务 到 TC
- 本地执行 SQL,同时生成快照(Undo Log)
- 假设全部成功,TM 通知 TC 提交 → TC 通知所有 RM 清理 Undo Log
- 要是有失败,TC 通知所有 RM回滚→ 读取 Undo Log,恢复数据
五、源码入口解析
Seata 的核心源码许可从以下几个包入手:
- TM(事务发起)
io.seata.tm.api.GlobalTransaction- 入口方法:
begin() / commit() / rollback()
- RM(资源管理器)
io.seata.rm.datasource.DataSourceProxy- 拦截 JDBC 操作,生成 Undo Log
- TC(协调器)
io.seata.server.coordinator.DefaultCoordinator- 接收 TM/RM 的请求,维护全局事务状态机
- Undo Log 存储
undo_log表:保存快照,用于回滚
六、实战中的坑点
- Undo Log 表膨胀
- 需定期清理已完成事务的快照
- 跨服务调用必须带 XID
- 否则 TC 无法识别事务链路
- 性能影响
- AT 模式性能损耗一般在 10% 左右,需要结合业务选择 TCC 或 Saga
七、总结
一句话记住 Seata:
Seata = TM + RM + TC,帮你把跨服务事务当成本地事务一样用。
对于日常开发:
- 如果业务简单,直接上AT 模式,几乎零侵入
- 假如要求高性能且能接受开发成本,用TCC
- 如果是长事务场景(比如跨天结算),考虑Saga

浙公网安备 33010602011771号