← 返回题目列表

Saga 模式的原理是什么?适合什么场景?

高频 中等 第 7 / 27 题 更新于 2026/07/28
Saga长事务补偿

简化版

Saga 把一个长事务拆成一串本地事务 T1、T2、…、Tn,每个本地事务配一个对应的补偿操作 C1、C2、…、Cn。正常时顺序执行 T1→T2→…→Tn;中途某步 Ti 失败,就反向依次执行已完成步骤的补偿 Ci-1→…→C1,把之前做过的都「撤销」,达到最终一致。它没有资源锁定、无隔离性,适合流程长、步骤多、每步都能补偿的业务(如旅游下单:订机票+订酒店+租车)。

详细版

核心组成

  • 正向操作 Ti:一个独立的本地事务,做完就提交(不像 2PC/TCC 有预留态)。
  • 补偿操作 Ci:Ti 的「语义反向操作」,用于撤销 Ti 的效果(订了票就退票、扣了款就退款)。

执行逻辑

  • 顺利:T1 → T2 → … → Tn,全部成功,事务完成。
  • 失败(假设 Ti 失败):执行 C(i-1) → … → C1,把前面成功的步骤逐个补偿掉。

两种协调方式

  • 编排式(Choreography,事件驱动):无中心协调者,每个服务完成后发事件,下一个服务监听事件继续。去中心化、松耦合,但流程分散难追踪。
  • 编制式(Orchestration,中心协调):有一个 Saga 协调器(编排器)按定义好的流程依次调用各服务、失败时调用补偿。流程集中、易监控,但协调器是核心。

关键特点:无锁、无隔离性(中间态对外可见,可能脏读)、补偿必须幂等且尽量能成功。

完整版教学

一、Saga 的思想:能撤销就不用锁

2PC/TCC 都靠「预留 + 锁定」保证隔离性,代价是资源占用。Saga 反其道而行:每步直接提交(不预留),出错了再用补偿操作反向撤销。就像你网购下了一串单,某单出问题就把前面的都退掉。好处是全程无锁、每步都是普通本地事务、性能好、特别适合耗时长的流程(几秒到几小时甚至跨天的业务)。代价是牺牲隔离性——因为每步都真提交了,中间状态对外是可见的(别人可能看到「机票订了但整个行程还没成」的中间态)。

二、编排式 vs 编制式

编排式(Choreography):靠事件驱动,去中心化。订单服务下单后发「订单已创建」事件 → 库存服务监听到就扣库存、发「库存已扣」事件 → 支付服务监听到就扣款……失败则发补偿事件反向传播。优点是服务间松耦合、无单点;缺点是流程隐藏在一堆事件里,难以看清全貌、难排查、容易形成循环依赖。适合步骤少(2-4 步)的简单流程。

编制式(Orchestration):一个中央 Saga 编排器持有完整流程定义,像总指挥一样依次调用 T1、T2…,某步失败就依次调用补偿。优点是流程集中可见、易监控、易维护、好排障;缺点是编排器成为核心组件(需高可用)。步骤多、流程复杂时首选编制式。

记忆点:步骤少用编排式(省一个协调器),步骤多/流程复杂用编制式(要一个能看清全局的总指挥)。

三、补偿操作的设计难点

补偿是 Saga 的灵魂,也是难点:

  • 必须幂等:补偿可能因重试被调多次,要保证多次执行等于一次。
  • 可能面对「补偿一个还没完成的操作」:要能处理(类似 TCC 的空回滚),通常靠记录每步状态判断。
  • 有些操作难以补偿:比如「已经发出的短信」「已扣的话费」无法真正撤销,只能用「反向业务」弥补(再发一条更正短信、退话费),设计时要评估每步是否可补偿。
  • 补偿失败怎么办:补偿本身也可能失败,要不断重试 + 告警 + 人工兜底,所以补偿逻辑要尽量简单可靠。

四、Saga 的隔离性问题及缓解

因为无锁、每步真提交,Saga 有脏读/脏写风险:事务执行到一半时,中间数据对其他事务可见,别人可能基于这个「注定要被补偿的」中间态做决策。缓解手段:

  • 语义锁:在业务字段上加「处理中」标记(类似应用层锁),别的事务看到就避让。
  • 预留 / 冻结:对关键资源用类似 TCC 的预留(Saga 和 TCC 可结合)。
  • 重排序:把「不可补偿/影响大」的步骤放到最后,尽量减少需要补偿的范围。

五、Saga vs TCC

维度TCCSaga
阶段Try/Confirm/Cancel 三方法正向 T + 补偿 C 两方法
隔离性有(预留隔离)无(中间态可见)
资源有预留/冻结无预留,直接提交
侵入大(三个方法+冻结字段)中(一个补偿方法)
适用短事务、强约束资源长流程、可补偿

六、常见误区与追问

这道题不能只背概念,要把「Saga 模式」放回真实分布式系统里解释:谁发起、谁协调、状态如何变化、失败后怎么兜底,以及它和性能、可用性、一致性的取舍。

回答层次要讲清的内容容易漏掉的边界
核心结论Saga 把长事务拆成一串本地事务,每步都有对应补偿操作,失败时按反向顺序补偿不要停在名词解释
流程机制执行本地事务 T1 -> 执行 T2/T3 -> 某一步失败 -> 按反向顺序执行补偿 C2/C1 -> 通过重试和状态机保证最终一致说明触发方、参与方、状态变化和兜底
工程取舍订旅行套餐时先订机票、酒店、租车,租车失败后依次取消酒店和机票分布式事务没有免费强一致,性能、可用性和业务侵入一定要取舍
Saga 模式 面试拆解:
1. 执行本地事务 T1
2. 执行 T2/T3
3. 某一步失败
4. 按反向顺序执行补偿 C2/C1
5. 通过重试和状态机保证最终一致

记忆钩子:先说本地事务失效的原因,再拆协调、补偿、消息、幂等、对账和回滚边界;回答时要紧扣「Saga 模式」这道题,不要把相邻概念混成一段泛泛的分布式套话。

  • 误区:Saga 可以像本地事务一样回滚。 Saga 是业务补偿,不是数据库 undo,补偿动作可能不是完全反向。
  • 误区:所有步骤都适合 Saga。 不可补偿或补偿成本极高的动作不适合直接放进 Saga。
  • 误区:Saga 不需要幂等。 每个正向和补偿步骤都可能重试,必须幂等。
  • 追问:编排式和协同式 Saga 区别是什么? 编排式由中心协调器控制流程,协同式由事件驱动各服务自治流转。
  • 追问:Saga 适合什么业务? 长流程、多步骤、允许中间状态和业务补偿的场景。
  • 追问:Saga 最大风险是什么? 补偿失败或补偿语义不完整,需要告警和人工兜底。

七、加强记忆

Saga 把长事务拆成一串本地事务 T1…Tn,每个配补偿 C1…Cn,正常顺序执行,失败则反向依次补偿已完成的步骤,达到最终一致。核心思想是「能补偿就不用锁」——每步直接提交、全程无锁、性能好,代价是无隔离性(中间态可见、有脏读)。协调方式分编排式(事件驱动、去中心、适合简单流程)和编制式(中央编排器、适合复杂流程)。补偿必须幂等、要处理不可补偿操作和补偿失败。适合旅游订票、跨多服务的长业务流程。