在开发系统时,你可能遇到过这样的问题:
用户下单时,需要同时扣减库存、生成订单、创建支付信息。如果中间有一步失败了,整个流程该怎么办?
在单体应用里,我们可以用 数据库事务 来“全部成功或全部失败”。但在 分布式系统 中,不同服务用的可能是不同数据库、部署在不同服务器上,传统事务就不再适用了。
这时,就需要用到一种新的事务解决方案——Saga 模式。
一、什么是 Saga 模式?
Saga 模式是一种分布式事务解决方案,用于在多个服务之间协调事务的执行。
它的核心思想是:
把一个大事务拆成多个小事务,每个小事务都成功了才算成功;如果中间失败了,就执行相应的“补偿操作”把之前做过的事“撤销”掉。
通俗一点来说:
“一步错了,退一步”,每走一步都准备好“退回去”的方法。
二、举个简单的生活例子
想象你在网上买东西,流程如下:
- 扣库存
- 创建订单
- 发起支付
如果第3步失败了,就需要:
- 把订单取消
- 把库存加回来
这就是一个 Saga 模式的完整流程:每一步操作都配有“撤回动作”。
三、Saga 模式的工作方式
Saga 模式将一个大事务拆分成多个“局部事务(Local Transaction)”,每个事务包含:
- 执行动作(Action):比如“扣库存”、“创建订单”
- 补偿动作(Compensation):比如“恢复库存”、“取消订单”
Saga 有两种主要实现方式:
| 模式 | 描述 | 特点 |
|---|---|---|
| 1. 编排模式(Orchestration) | 一个中心服务负责调度所有子事务的执行和补偿 | 控制集中、流程清晰 |
| 2. 协作模式(Choreography) | 每个服务自己决定下一步该通知谁,自己负责补偿 | 松耦合、灵活性高 |
四、Saga 模式和传统事务的区别
| 对比项 | 传统数据库事务 | Saga 模式 |
|---|---|---|
| 场景 | 单体应用 | 分布式系统 |
| 技术基础 | 数据库的 ACID | 服务之间的协调 |
| 整体回滚 | 数据库自动 | 需要自己编写补偿逻辑 |
| 性能 | 相对慢,锁资源多 | 性能好,不锁分布式资源 |
| 实现难度 | 简单 | 相对复杂,需要编写补偿操作 |
五、Saga 模式适用场景
- 电商平台:下单、扣库存、支付等多个服务协作
- 金融系统:转账需要跨银行、跨系统操作
- 旅游平台:机票、酒店、租车等联合预订
- 企业服务系统:一个业务流程涉及多个子系统
六、Saga 实现中的关键点
1. 补偿逻辑要完整可靠
每个服务都要有“撤销功能”,比如订单取消、库存恢复等。
2. 避免部分成功导致脏数据
在发生失败后,补偿必须执行,避免系统数据不一致。
3. 考虑幂等性
比如:取消订单操作要幂等(多次调用结果一样),避免补偿失败或重复执行出问题。
4. 异步处理 + 重试机制
Saga 模式通常是异步的,要考虑失败重试和状态监控。
七、一个代码层面的简单流程(伪代码)
try:
扣库存() → 成功
创建订单() → 成功
创建支付() → 失败!
// 开始补偿
取消订单()
恢复库存()
except:
log("事务失败,已补偿")
这就是一个典型的 Saga 编排流程。
八、开源框架推荐
想实际使用 Saga,可以选择一些成熟的框架,比如:
- Seata(阿里):支持 AT/TCC/Saga/XA 四种事务模式
- Axon Framework(Java):支持 Saga 的事件驱动模型
- MicroProfile LRA(Java EE):微服务中的长事务规范
- Netflix Conductor:编排型 Saga 工作流引擎
九、总结
| 特点 | 内容 |
|---|---|
| 定义 | Saga 是一种分布式事务协调模式,按步骤执行、失败补偿 |
| 原理 | 一个大事务 = 一系列局部事务 + 补偿操作 |
| 优点 | 不锁资源、高性能、适合分布式场景 |
| 难点 | 需要开发补偿逻辑,测试复杂性提升 |
| 适合谁 | 涉及多个微服务协同处理的业务系统 |
十、建议给初学者的学习步骤
- 理解本地事务和分布式事务的区别
- 学会画出完整的业务流程图
- 练习写出每一步的补偿逻辑
- 使用消息队列或工作流框架模拟 Saga 执行
- 尝试用 Seata 等框架做简单项目实践
Saga 模式是分布式系统中保持“最终一致性”的聪明办法,它不追求一瞬间的一致,而是允许过程中的不一致,但保证最终状态是对的。
2603

被折叠的 条评论
为什么被折叠?



