← 返回题目列表

什么是补偿机制?分布式系统中如何设计补偿任务?

高频 中等 第 6 / 25 题 更新于 2026/07/28
补偿机制补偿任务异常修复

简化版

补偿机制是在分布式流程部分失败或状态长期不一致时,通过反向操作、重试操作或修复操作把系统拉回正确状态。设计补偿任务要明确可补偿条件、补偿动作、幂等控制、重试策略、人工介入和对账来源。

详细版

补偿常见于最终一致场景。例如支付成功但订单状态未更新、发券失败、库存冻结未释放、消息消费失败等。

补偿设计要点:

  1. 定义异常状态:哪些状态需要补偿。
  2. 找到权威事实:以支付流水、订单状态、库存流水等为准。
  3. 设计补偿动作:重试、回滚、冲正、释放资源。
  4. 保证幂等:补偿任务可能重复执行。
  5. 控制重试:避免无限补偿打爆下游。
  6. 记录补偿日志:方便审计和排查。
  7. 人工兜底:复杂异常进入人工处理。

补偿不是简单回滚。很多外部动作无法真正撤销,只能用业务上的冲正或修复动作解决。

完整版教学

一、为什么分布式系统需要补偿

分布式流程经常不是一次性全部成功。比如支付成功后要更新订单、加积分、发通知,其中支付成功了,但订单服务临时超时。

此时不能把支付事实当作不存在,也不能让订单永远停在待支付。系统需要一个后续修复动作,把订单状态补成已支付。

补偿机制就是为这种“中间失败但不能简单回滚”的场景准备的。

二、补偿不等于数据库回滚

本地事务回滚是把未提交的修改撤销;补偿是在业务动作已经发生后,用新的业务动作修正结果。

例如用户付款已经真实扣款,不能通过数据库回滚让银行把钱自动退回。如果要撤销,只能发起退款或冲正,这本身是一个新的业务流程。

所以补偿要理解业务语义:有些是重试完成,有些是反向操作,有些是标记异常等待人工处理。

三、补偿任务怎么找异常

补偿任务需要一个权威事实来源。

例如支付场景中,支付渠道流水通常是权威事实。补偿任务可以扫描:

支付流水 = SUCCESS
订单状态 != PAID
超过 5 分钟仍未修复

发现后调用订单服务补更新状态。这里不能只看订单状态,因为订单状态可能就是异常的一方。

四、补偿动作如何设计幂等

补偿任务会反复扫描,人工也可能重复触发,所以补偿动作必须幂等。

例如释放库存:

update stock_reservation
set status = 'RELEASED'
where reservation_id = ? and status = 'FROZEN';

如果已经释放,再执行一次影响行数为 0,不会重复增加库存。所有补偿都应该类似这样用状态条件、唯一流水或版本号保护。

五、补偿失败怎么办

补偿本身也可能失败。不能无限循环无脑重试。

常见做法是记录补偿次数、下一次重试时间、最后错误信息。超过阈值后进入人工处理池,并触发告警。

资金、库存、账单类补偿还要有审计日志,记录谁触发、补了什么、补偿前后状态是什么。

六、补偿设计的常见误区

第一个误区是把补偿理解成“反向 SQL”。很多业务动作一旦对外发生,就不能靠改本地数据库撤回。例如第三方支付成功、短信已经发出、优惠券已经被用户使用,这些都需要业务化的冲正、撤销或人工处理。

第二个误区是补偿任务没有时间窗口。刚发生的异步延迟不一定是异常,如果立即补偿,可能和正常链路并发冲突。通常会设置观察窗口,例如支付成功超过 5 分钟订单仍未更新,才进入补偿。

第三个误区是补偿没有优先级。资金、账单、库存类异常要高优先级处理;通知、埋点、统计类异常可以低优先级批量修复。补偿系统本身也要限流,否则故障恢复时可能把下游再次打垮。

七、常见误区与追问

这道题要紧扣「补偿事务」本身回答,不能把它混成泛泛的数据一致性套话。面试官通常会追问“写入怎么确认、失败怎么补、旧数据怎么防、成本在哪里”,所以回答要覆盖一致性目标、写入顺序、消息投递、幂等、补偿、对账和读写体验。

回答层次要讲清的内容容易漏掉的边界
核心结论补偿事务是在分布式操作部分成功后,通过反向动作或修正动作把业务状态拉回可接受状态不要停在名词解释
流程机制记录业务状态 -> 执行正向步骤 -> 发现后续失败 -> 判断可补偿动作 -> 执行补偿或重试 -> 对账确认最终状态要说清触发点、状态变化、确认点和失败兜底
工程取舍下单成功但发券失败时,可以取消订单、补发券或标记人工处理,具体取决于业务语义一致性方案本质是在强一致成本、系统可用性、延迟和业务可接受的不一致窗口之间取舍
补偿事务 面试拆解:
1. 记录业务状态
2. 执行正向步骤
3. 发现后续失败
4. 判断可补偿动作
5. 执行补偿或重试
6. 对账确认最终状态

记忆钩子:先给结论,再拆流程,再讲数字例子和失败边界;回答「补偿事务」时要围绕题目问法收束,不要把相邻概念堆成一段没有重点的名词清单。

  • 误区:补偿就是简单回滚。 很多业务动作不可物理回滚,只能做反向业务动作或修正状态。
  • 误区:补偿一定能恢复到原样。 发货、扣款、外部通知等动作可能只能人工处理或追加冲正。
  • 误区:补偿逻辑可以事后再补。 没有状态机和幂等记录,事故后很难可靠补偿。
  • 追问:补偿事务和本地事务区别? 本地事务靠数据库原子回滚,补偿事务靠业务动作最终收敛。
  • 追问:补偿动作如何保证幂等? 用业务单号、状态机、补偿记录和唯一约束防重复。
  • 追问:什么时候适合补偿? 跨服务长流程、可接受最终一致且每步有明确反向或修正动作的场景。

八、加强记忆

补偿机制的核心是“承认分布式流程会中途断,然后设计把它拉回正确状态的动作”。补偿要找权威事实、动作要幂等、失败要重试和告警,复杂情况要能人工接管。