seata解决分布式事务
目录
1. AT 模式(Automatic Transaction,最常用、无侵入)
2. TCC 模式(Try-Confirm-Cancel,高性能、高侵入)
一、Seata 是什么
Seata(Simple Extensible Autonomous Transaction Architecture)是阿里开源、现捐给 Apache 的一站式分布式事务解决方案,目标是让微服务下的分布式事务像本地事务一样简单易用。
它要解决的核心问题:跨库 / 跨服务的多个操作,要么全成功,要么全回滚(原子性),并保证数据一致性。
二、核心架构:三大角色(所有模式通用)
Seata 把分布式事务抽象成三个角色,协同完成两阶段提交(2PC):
-
TC(Transaction Coordinator,事务协调器)
- 独立部署的 Seata Server(集群保证高可用)
- 职责:全局事务的 “大脑”
- 生成全局唯一事务号 XID
- 维护全局 / 分支事务状态
- 驱动全局提交或回滚
-
TM(Transaction Manager,事务管理器)
- 部署在业务发起方(如订单服务)
- 职责:定义全局事务边界
- 开启全局事务(向 TC 要 XID)
- 提交 / 回滚全局事务
-
RM(Resource Manager,资源管理器)
- 部署在每个参与事务的微服务(库存 / 账户 / 订单服务)
- 职责:管理本地资源,响应 TC 指令
- 注册分支事务到 TC
- 执行本地事务、生成回滚日志
- 按 TC 指令提交 / 回滚分支
标准流程(所有模式通用):
- TM 向 TC 申请开启全局事务 → TC 生成 XID 返回
- XID 在服务调用链路上透传
- 每个 RM 收到 XID,向 TC 注册分支事务
- TM 决议:全局提交或回滚
- TC 通知所有 RM:提交 / 回滚分支事务
三、四大事务模式(核心:怎么解决分布式事务)
Seata 提供 AT、TCC、Saga、XA 四种模式,覆盖从强一致→最终一致、低侵入→高灵活的全场景。
1. AT 模式(Automatic Transaction,最常用、无侵入)
定位:基于本地事务 + 自动回滚日志的增强版 2PC,业务代码零侵入,强一致(全局锁隔离)。
原理:两阶段提交(核心是 undo_log + 全局锁)
- 一阶段(Prepare + 本地提交)
- RM 拦截业务 SQL(如 update)
- 生成 before_image(修改前数据) 和 after_image(修改后数据)
- 在同一个本地事务里:执行业务 SQL + 插入 undo_log(回滚日志)
- 提交本地事务,释放本地锁和连接
- 关键:提交前必须先拿到全局锁(防止其他事务改同一条数据)
二阶段(Commit/Rollback)
- 全局提交:TC 通知 RM → RM 异步删除 undo_log(极快)
- 全局回滚:TC 通知 RM → RM 根据 undo_log 生成反向 SQL,恢复数据到 before_image 状态
核心表:undo_log(自动创建)
CREATE TABLE undo_log (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
xid VARCHAR(100) NOT NULL, -- 全局事务ID
branch_id BIGINT NOT NULL, -- 分支事务ID
rollback_info LONGBLOB NOT NULL, -- 回滚日志(before_image)
log_status INT NOT NULL, -- 状态:0正常,1已回滚
log_created DATETIME NOT NULL,
log_modified DATETIME NOT NULL,
UNIQUE KEY ux_undo_log (xid, branch_id)
);
优点:无侵入、强一致、性能较好(一阶段提交本地事务)缺点:依赖关系型数据库、全局锁可能导致冲突、有少量性能损耗适用:90% 微服务场景(电商下单、库存扣减、订单创建)
2. TCC 模式(Try-Confirm-Cancel,高性能、高侵入)
定位:业务层手动实现的 2PC,无全局锁,性能最高,但代码侵入强。
原理:三阶段(完全由业务代码控制)
- Try(一阶段:资源检查 + 预留)
- 检查业务合法性(如库存是否充足)
- 预留资源(如冻结库存、冻结金额)
- 不真正扣减,只 “占坑”
- Confirm(二阶段:确认提交)
- 真正执行业务操作(扣减冻结库存、扣减冻结金额)
- 必须幂等(防止重复调用)
- Cancel(二阶段:取消回滚)
- 释放预留资源(解冻库存、解冻金额)
- 必须幂等、防空回滚
示例(库存服务)
// Try:冻结库存
public boolean tryDeduct(Long goodsId, int count);
// Confirm:确认扣减
public boolean confirmDeduct(Long goodsId, int count);
// Cancel:解冻库存
public boolean cancelDeduct(Long goodsId, int count);
优点:无全局锁、高性能、灵活控制资源缺点:侵入极强(写 3 倍代码)、需处理幂等 / 空回滚 / 悬挂适用:高并发、对性能敏感场景(支付扣款、账户冻结、红包发放)
3. Saga 模式(长事务、最终一致、无锁)
定位:长周期分布式事务,拆分为本地子事务,无锁、异步化、最终一致。
原理:正向执行 + 补偿事务(状态机驱动)
- 将全局事务拆成一串本地子事务(T1→T2→T3→…→Tn)
- 每个子事务有对应的补偿事务(C1→C2→C3→…→Cn)
- 执行规则:
- 正向依次执行 T1、T2、T3…
- 若全部成功:正常结束
- 若 T3 失败:反向执行补偿 C2、C1,回滚已提交的 T2、T1
两种实现:
- 状态机模式(推荐):Seata 内置状态机引擎,配置化定义流程与补偿,低侵入
- 编排模式:基于消息队列 / 定时任务,完全异步,适合跨系统长流程
优点:无锁、支持长事务、异步化、跨技术栈缺点:最终一致(中间态不一致)、补偿逻辑复杂、无隔离适用:长周期、跨系统、异步流程(订单→支付→物流→出库→短信通知)
4. XA 模式(数据库原生强一致、性能差)
定位:标准 X/Open XA 协议实现,强一致、无侵入、性能低。
原理:数据库原生 2PC
- 一阶段(Prepare):RM 执行 SQL,但不提交本地事务,只锁资源,向 TC 报告 OK
- 二阶段(Commit/Rollback):
- 全部分支 Prepare OK → TC 指令 Commit → RM 提交本地事务,释放锁
- 任一分支失败 → TC 指令 Rollback → RM 回滚本地事务,释放锁
优点:强一致、无侵入、数据库原生支持缺点:性能极低(一阶段锁资源直到二阶段)、长锁风险、依赖 XA 数据库适用:强一致要求极高、并发低场景(金融核心、账务系统)
四、AT 模式深度拆解(最核心)
1. 全局锁机制(解决隔离性)
- 一阶段提交前,RM 必须先拿到该记录的全局锁
- 全局锁存在 TC(Redis/DB 存储)
- 拿不到锁 → 等待(超时回滚)→ 避免脏写
- 示例:事务 A 扣减库存,事务 B 同时扣减同库存 → B 阻塞直到 A 提交 / 回滚
2. 回滚流程(保证原子性)
- 全局事务失败 → TC 通知所有 RM 回滚
- RM 收到回滚指令 → 读取 undo_log 的 before_image
- 生成反向 SQL(如 UPDATE stock SET count=100 WHERE id=1)
- 执行反向 SQL → 恢复数据
- 删除 undo_log → 回滚完成
3. 与传统 2PC 的区别(性能关键)
- 传统 2PC:一阶段不提交,锁资源直到二阶段 → 长锁、性能差
- Seata AT:一阶段提交本地事务,释放锁和连接 → 短锁、性能好,仅靠 undo_log 回滚
五、模式对比与选型
| 维度 | AT 模式 | TCC 模式 | Saga 模式 | XA 模式 |
|---|---|---|---|---|
| 一致性 | 强一致(全局锁) | 强一致(业务控制) | 最终一致 | 强一致 |
| 侵入性 | 无(零代码) | 高(三阶段接口) | 低(状态机) | 无 |
| 性能 | 中(有锁) | 高(无锁) | 高(无锁) | 低(长锁) |
| 适用场景 | 90% 微服务 | 高并发、性能敏感 | 长流程、跨系统 | 强一致、低并发 |
选型建议:
- 优先用 AT 模式(简单、够用、性能好)
- 高并发 / 性能敏感 → TCC 模式
- 长流程 / 跨系统 → Saga 模式
- 金融核心 / 强一致 → XA 模式(或 TCC)
六、快速落地(Spring Boot + AT 模式)
1. 依赖
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.7.1</version>
</dependency>
2. 配置(application.yml)
seata:
application-id: order-service
tx-service-group: my-tx-group # 事务组名
server:
addr: 127.0.0.1:8091 # TC 地址
config:
type: file
registry:
type: file
3. 业务代码(零侵入)
@Service
public class OrderService {
@GlobalTransactional // 开启全局事务(TM)
public void createOrder(Order order) {
// 1. 扣减库存(库存服务,RM)
stockService.deduct(order.getGoodsId(), order.getCount());
// 2. 扣减余额(账户服务,RM)
accountService.deduct(order.getUserId(), order.getAmount());
// 3. 创建订单(订单服务,RM)
orderMapper.insert(order);
}
}
4. 初始化 undo_log
在每个业务库执行 undo_log 建表语句(前面已给出)。
七、总结:Seata 怎么解决分布式事务
- 架构上:通过 TC/TM/RM 三角色,将分布式事务抽象为统一的 2PC 模型
- 模式上:提供 AT/TCC/Saga/XA 四种模式,覆盖强一致→最终一致、低侵入→高性能全场景
- AT 核心:一阶段提交本地事务 + undo_log 记录快照 + 全局锁隔离;二阶段异步删除日志或反向回滚,兼顾一致性与性能
- 本质:把分布式事务的复杂性封装在框架内部,让业务像写本地事务一样简单
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)