Seata的实现原理主要围绕其核心架构(TC/TM/RM)和事务模式(如AT、TCC等)展开,通过协调全局事务与分支事务的协作保证数据一致性。以下是核心实现原理的详细解析:
⚙️ 一、核心架构协作机制
Seata通过 TC(事务协调器)、TM(事务管理器)、RM(资源管理器) 三组件协同工作:
-
全局事务启动(TM主导)
- TM通过
@GlobalTransactional
注解标记事务起点,向TC申请开启全局事务,生成全局唯一 XID 。 - XID通过RPC调用链传播至所有关联服务(如订单服务→库存服务→账户服务)。
- TM通过
-
分支事务注册(RM执行)
- 各服务的RM向TC注册分支事务,关联到同一XID的全局事务中。
- RM执行本地事务(如更新数据库),并在提交前记录 回滚日志(undo_log)(AT模式)或调用TCC预留接口(TCC模式)。
-
全局事务决议(TC调度)
- TM根据业务结果通知TC提交或回滚全局事务。
- TC驱动所有RM执行最终操作:
- 提交:异步删除undo_log(AT模式)或调用Confirm接口(TCC模式)。
- 回滚:根据undo_log生成反向SQL补偿数据(AT模式)或调用Cancel接口(TCC模式)。
✅ 关键点:XID在调用链中透传,确保所有分支事务归属同一全局事务;TC作为中央调度器维护事务状态。
🔧 二、AT模式(自动补偿)的实现细节
AT模式是Seata的默认模式,通过 SQL解析 + 回滚日志 实现无侵入事务控制:
1. 第一阶段:本地事务提交与日志记录
- SQL拦截与解析
RM拦截业务SQL(如UPDATE product SET stock=stock-1
),解析语义并提取操作的数据范围。 - 生成数据镜像
- 查询当前数据快照作为 前镜像(before_image)(修改前的数据)。
- 执行业务SQL,查询修改后数据作为 后镜像(after_image) 。
- 记录undo_log
在同一本地事务中提交业务SQL和undo_log(包含前后镜像的JSON),并向TC申请全局锁(防止其他事务修改同一数据)。
2. 第二阶段:异步提交或补偿回滚
- 提交:TC异步删除undo_log,释放全局锁(毫秒级完成)。
- 回滚:
- RM根据XID和分支ID查找undo_log,对比后镜像与当前数据:
- 若一致,用前镜像生成反向SQL(如
UPDATE product SET stock=stock+1
)执行补偿。 - 若不一致(数据被其他事务修改),根据策略(如重试或人工干预)处理。
- 若一致,用前镜像生成反向SQL(如
- 补偿操作在本地事务中完成,确保原子性。
- RM根据XID和分支ID查找undo_log,对比后镜像与当前数据:
⚠️ 隔离性保障:通过全局锁机制实现写隔离。例如:事务A持有数据X的全局锁时,事务B需等待锁释放才能修改X,避免脏写。
🔄 三、其他模式的实现差异
模式 | 实现原理 | 适用场景 |
---|---|---|
TCC | 业务层手动实现三阶段: |
- Try:预留资源(如冻结库存)
- Confirm:提交资源(实际扣减)
- Cancel:释放资源(解冻库存)
需保证幂等性和空回滚处理。 | 高一致性场景(支付、转账) |
| SAGA | 将长事务拆分为子任务链,每个子事务提交后触发下一个;失败时按逆序调用补偿操作。 | 跨服务长流程(保险理赔、物流) |
| XA | 基于数据库XA协议: - 一阶段:RM执行SQL但不提交,持有数据库锁
- 二阶段:TC通知所有RM提交/回滚
强一致但性能低(同步阻塞)。 | 传统金融系统 |
⚠️ 四、性能与可靠性设计
- 全局锁优化
- 锁冲突时采用退避重试机制,超时自动回滚分支事务。
- 高并发场景建议避免跨服务操作同一行数据。
- 异步化处理
- AT模式二阶段提交异步删除undo_log,减少阻塞。
- 高可用部署
- TC支持集群化(如注册到Nacos),事务日志持久化到数据库(避免单点故障)。
💎 总结
Seata的核心实现围绕 XID全局事务链、分支事务状态管理 及 多模式补偿机制:
- AT模式:通过SQL解析+undo_log实现自动回滚,牺牲部分性能换取低侵入性;
- TCC/SAGA:业务层控制补偿逻辑,性能更高但开发复杂;
- 全局锁与异步设计:平衡一致性与并发性能,适合多数微服务场景。
实际选型需结合业务需求:简单场景用AT,高性能要求用TCC,长流程用SAGA,强一致用XA。