Saga 分布式事务模式 是一种用于管理长事务(Long Running Transaction, LRT) 的最终一致性方案,通过将事务拆分为多个本地事务,并定义补偿操作(Compensating Transaction)来回滚已完成的步骤。Saga 特别适用于跨多个微服务、需要长时间运行的业务流程(如电商订单、旅行预订)。
一、Saga 核心原理
- 事务拆分:将全局事务拆分为多个连续的本地事务(正向操作)。
- 补偿机制:为每个正向操作定义逆向操作(如取消订单、恢复库存)。
- 最终一致性:通过重试或补偿操作,确保所有服务最终一致。
二、Saga 的两种协调模式
1. 编排式(Choreography)
-
原理:各服务通过事件(Event)自主触发后续操作,无中心协调器。
-
流程示例:
OrderServiceInventoryServicePaymentServiceNotificationService创建订单,发送「OrderCreated」事件扣减库存发送「InventoryReserved」事件扣款发送「PaymentCompleted」事件发送订单确认邮件发送「InventoryReserveFailed」事件取消订单alt[扣减库存失败]OrderServiceInventoryServicePaymentServiceNotificationService -
优点:
- 去中心化,服务间解耦。
- 适合简单流程,灵活性高。
-
缺点:
- 流程逻辑分散,调试困难。
- 可能产生循环依赖。
2. 编排式(Orchestration)
-
原理:由协调器(Orchestrator) 集中控制事务流程,调用各服务接口。
-
流程示例:
UserOrchestratorOrderServiceInventoryServicePaymentService提交订单请求创建订单订单ID=123扣减库存(订单ID=123)成功扣款(订单ID=123)成功订单完成取消订单(订单ID=123)恢复库存(订单ID=123)订单失败alt[扣款成功][扣款失败]UserOrchestratorOrderServiceInventoryServicePaymentService -
优点:
- 流程集中管理,易监控和调试。
- 避免服务间直接依赖。
-
缺点:
- 协调器可能成为单点瓶颈。
- 需额外维护协调器逻辑。
三、Saga 的实现步骤
1. 定义事务步骤与补偿操作
- 正向操作:
CreateOrder→ReserveInventory→ChargePayment。 - 补偿操作:
CancelOrder←RestoreInventory←RefundPayment。
2. 事务状态管理
-
数据库设计:记录全局事务状态(进行中、已完成、已取消)。
CREATE TABLE saga_log ( saga_id VARCHAR(64) PRIMARY KEY, status ENUM('pending', 'completed', 'compensating', 'failed'), current_step INT, created_at DATETIME, updated_at DATETIME );
3. 实现补偿逻辑
- 幂等性设计:补偿操作需支持重试(如通过唯一事务ID去重)。
- 超时控制:设置步骤超时阈值,超时后触发补偿。
4. 异常处理
- 重试策略:对暂时性错误(如网络抖动)进行指数退避重试。
- 人工干预:最终失败时记录日志,提供管理界面手动修复。
四、Saga 的适用场景
- 长事务流程:跨多个服务、执行时间较长的业务(如旅行预订:航班+酒店+租车)。
- 无法锁资源的场景:不适合预占资源的业务(如秒杀库存,需用 TCC)。
- 跨组织系统集成:与外部系统交互,无法控制其事务(如第三方支付回调)。
五、Saga vs TCC 对比
| 维度 | Saga | TCC |
|---|---|---|
| 一致性模型 | 最终一致性 | 最终一致性 |
| 事务时长 | 长事务(分钟~小时) | 短事务(秒级) |
| 资源锁定 | 无锁,异步补偿 | 资源预留(Try 阶段冻结资源) |
| 实现复杂度 | 中(需管理补偿逻辑) | 高(需处理悬挂、空回滚) |
| 适用场景 | 跨服务长流程(如电商订单) | 高并发短事务(如秒杀) |
六、Saga 的挑战与解决方案
1. 数据不一致窗口
-
问题:补偿操作完成前,系统处于不一致状态(如订单已取消但库存未恢复)。
-
解决方案:
- 业务层容忍短暂不一致(如显示“订单取消中”状态)。
- 对账系统定期修复数据差异。
2. 补偿操作失败
-
问题:补偿操作自身失败(如恢复库存时服务不可用)。
-
解决方案:
- 重试补偿操作,结合告警通知人工介入。
- 记录详细日志,便于追踪问题。
3. 事务状态跟踪
-
问题:分布式环境下跟踪全局事务状态困难。
-
解决方案:
- 使用唯一
saga_id贯穿所有服务调用。 - 集中式协调器(Orchestration 模式)维护状态机。
- 使用唯一
七、最佳实践案例:电商订单系统
场景描述
- 用户下单 → 扣减库存 → 支付 → 通知物流。
- 若支付失败 → 取消订单 → 恢复库存 → 通知用户。
Saga 流程(编排式)
UserOrchestratorOrderServiceInventoryServicePaymentServiceLogisticsService提交订单创建订单订单创建成功扣减库存库存扣减成功执行支付支付成功生成运单运单已生成订单完成取消订单恢复库存订单失败alt[支付成功][支付失败]UserOrchestratorOrderServiceInventoryServicePaymentServiceLogisticsService
八、技术选型建议
| 组件 | 推荐方案 | 作用 |
|---|---|---|
| 协调器框架 | Camunda、Zeebe | 支持状态机管理、可视化流程编排 |
| 消息队列 | Kafka、RabbitMQ | 事件驱动通信(Choreography 模式) |
| 分布式追踪 | Jaeger、Zipkin | 跟踪 Saga 事务链路,便于调试 |
| 对账系统 | 自研定时任务 + 数据比对工具 | 定期修复数据不一致 |
九、总结
Saga 通过 事务拆分 + 补偿机制 实现了分布式长事务的最终一致性,其核心设计可归纳为:
最终一致性 = 正向操作 + 逆向补偿 + 幂等性 + 重试机制
选型建议:
- 长事务、跨服务:选择 Saga(如电商订单、旅行预订)。
- 高并发、短事务:选择 TCC 或可靠消息队列。
- 外部系统交互:结合 Saga 编排式与最大努力通知。
设计公式:
Saga = 本地事务链 + 补偿操作 + 协调模式(编排/编排) → 最终一致性