首页/开发/系统分析与架构设计速查/补偿事务与业务回滚

补偿事务与业务回滚

分布式流程无法物理回滚已完成的远程操作,只能执行语义相反的补偿动作(退款、释放库存、回发优惠券);补偿必须幂等、可重试且可审计。

补偿事务与业务回滚是什么

分布式流程里,已完成的远程操作无法物理回滚:扣款成功后下游失败,只能执行语义相反的动作——退款、释放库存、回发优惠券。这类动作叫补偿,它产生的是新的业务事实,而不是把历史抹掉,因此审计与对账必须能解释正向记录与补偿记录之间的关系。补偿动作要和正向操作一样被认真设计:幂等、可重试、可审计、有顺序要求,并且要明确哪些场景根本不可补偿。

基本信息

设计要点补偿语义明确,与正向操作一样纳入测试与评审
顺序通常逆序补偿,但要核对业务依赖(如已开票需先红冲)
幂等按业务单号去重,重复执行结果一致
重试区分可重试与需人工,超出上限转人工处置队列
审计正向与补偿记录成对留存,支持对账解释

典型使用场景

  • 跨服务下单:库存锁定成功但支付超时,需释放库存并关闭订单
  • 资金类流程:下游履约失败时发起退款,退款单据与原始支付单关联
  • 优惠券与积分:发放后流程失败需回补,避免额度被无效占用
  • 预约与占座:超时未确认时释放资源,把名额让给其他用户
  • 批量导入:部分条目失败时按批次回补已成功的部分
  • 对账差异修复:发现账实不符时用补偿记录修正并留痕

补偿设计检查

检查项说明常见缺陷
幂等重复执行结果一致,按业务单号去重网络重试造成重复退款
可重试区分可重试与需人工,超限转人工队列无限重试把下游打得更死
顺序逆序补偿,并核对业务依赖先退券后关单,客户仍在使用优惠
审计正向与补偿记录成对留存,可对账解释只有补偿记录,追溯不到原始单据
不可逆处理已发货、已对外通知等转人工流程系统自动尝试补偿却无法真正撤销

补偿动作实现要点

补偿动作实现要点
# 补偿动作示例:释放库存
# 1 幂等:以订单号 + 动作类型作为唯一键,重复调用直接返回成功
# 2 前置校验:确认该订单确实处于已锁定状态,避免误释放
# 3 分离重试:区分可重试(下游超时)与不可重试(数据非法)
# 4 记录:写入补偿流水,包含原因、次数、来源请求 ID
# 5 上限:超过重试上限进入人工队列并告警,不静默丢弃
# 6 对账:每日比对锁定与释放记录,差异条目自动列出待处理
补偿不是撤销:它产生新的业务事实,审计与对账必须能解释两条记录的关系,否则账目看起来是重复入账或凭空冲销。
不可补偿的场景必须提前识别(已发货、已通知外部机构、已消耗的权益),为它们设计人工介入流程,而不是让系统反复重试。

易错点

  • 补偿动作不幂等:重试造成重复退款或重复发券,资金损失难追回
  • 补偿链路缺少人工兜底:不可逆场景被反复自动重试,问题持续放大
  • 补偿与正向记录不对应:对账时无法解释差异来源
  • 无重试上限与告警:失败任务静默积压,业务长期处于不一致状态
  • 逆序补偿未核对业务依赖:发票未红冲就退款,财务口径出错

数据来源与参考

  • Hector Garcia-Molina & Kenneth Salem《Sagas》(SIGMOD, 1987)
  • Chris Richardson《Microservices Patterns》
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌