

























如果说 TCC 是分布式事务中的“强一致性”代表,那么 Saga 模式就是“最终一致性”和“长事务”的王者。
Saga 模式最早在 1987 年由普林斯顿大学提出,它的核心思想非常朴素:把一个长事务拆分成一系列的本地短事务。如果所有步骤都成功,事务就完成;如果某一步失败,就按逆序执行补偿操作,把之前的数据“修补”回去。
它特别适合那些流程长、涉及服务多、且允许短暂中间状态的业务场景(比如电商下单、物流履约、保险理赔)。
Saga 将一个全局事务拆解为一系列有序的本地事务(Local Transaction, $T_i$):
$$T_1, T_2, ..., T_n$$
每个本地事务 $T_i$ 都有一个对应的补偿事务(Compensating Transaction, $C_i$),用于撤销 $T_i$ 造成的影响。
Saga 模式在工程落地时,主要有两种流派,你需要根据业务复杂度来选择:
这是面试和架构选型中最常被问到的问题,我为你整理了一个对比表:
| 维度 | TCC (Try-Confirm-Cancel) | Saga 模式 |
|---|---|---|
| 一致性 | 最终一致性(较强) | 最终一致性(较弱,有中间状态) |
| 性能 | 高(无长锁),但有资源预留开销 | 极高(无锁,资源利用率高) |
| 业务侵入 | 极高(需写 Try/Confirm/Cancel 三套代码) | 中等(只需写正向逻辑 + 补偿逻辑) |
| 隔离性 | 较好(资源预留阶段隔离) | 差(事务未提交前,数据修改对其他事务可见) |
| 适用场景 | 核心资金交易、高并发、短流程 | 长流程、跨部门/跨公司调用、非核心资金流 |
Saga 的灵魂在于补偿机制。设计补偿时,你必须注意以下三个“坑”:
有些操作是不可逆的。
和 TCC 一样,Saga 的正向操作和补偿操作都必须是幂等的。
在 Go 语言中,通常使用状态机或专门的框架(如 dtm)来实现。如果不使用框架,伪代码逻辑如下:
// 协调器逻辑
func (o *OrderOrchestrator) CreateOrder(orderID string) error {
// 1. 开启 Saga 事务记录(记录状态为 "STARTED")
// 2. 执行正向流程
if err := o.orderService.Create(orderID); err != nil {
return err
}
if err := o.inventoryService.Reduce(orderID); err != nil {
// 3. 失败!触发补偿
o.compensate(orderID, "INVENTORY_FAILED")
return err
}
if err := o.paymentService.Pay(orderID); err != nil {
// 4. 失败!触发补偿
o.compensate(orderID, "PAYMENT_FAILED")
return err
}
// 5. 全部成功
return nil
}
// 补偿逻辑
func (o *OrderOrchestrator) compensate(orderID, failStage string) {
// 根据失败阶段,逆序执行补偿
switch failStage {
case "PAYMENT_FAILED":
// 支付失败,需要恢复库存
o.inventoryService.Restore(orderID)
// 然后继续执行下面的 order cancel
fallthrough
case "INVENTORY_FAILED":
// 库存失败,取消订单
o.orderService.Cancel(orderID)
}
}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。