补偿事务与业务回滚是什么
分布式流程里,已完成的远程操作无法物理回滚:扣款成功后下游失败,只能执行语义相反的动作——退款、释放库存、回发优惠券。这类动作叫补偿,它产生的是新的业务事实,而不是把历史抹掉,因此审计与对账必须能解释正向记录与补偿记录之间的关系。补偿动作要和正向操作一样被认真设计:幂等、可重试、可审计、有顺序要求,并且要明确哪些场景根本不可补偿。
基本信息
| 设计要点 | 补偿语义明确,与正向操作一样纳入测试与评审 |
|---|---|
| 顺序 | 通常逆序补偿,但要核对业务依赖(如已开票需先红冲) |
| 幂等 | 按业务单号去重,重复执行结果一致 |
| 重试 | 区分可重试与需人工,超出上限转人工处置队列 |
| 审计 | 正向与补偿记录成对留存,支持对账解释 |
典型使用场景
- 跨服务下单:库存锁定成功但支付超时,需释放库存并关闭订单
- 资金类流程:下游履约失败时发起退款,退款单据与原始支付单关联
- 优惠券与积分:发放后流程失败需回补,避免额度被无效占用
- 预约与占座:超时未确认时释放资源,把名额让给其他用户
- 批量导入:部分条目失败时按批次回补已成功的部分
- 对账差异修复:发现账实不符时用补偿记录修正并留痕
补偿设计检查
| 检查项 | 说明 | 常见缺陷 |
|---|---|---|
| 幂等 | 重复执行结果一致,按业务单号去重 | 网络重试造成重复退款 |
| 可重试 | 区分可重试与需人工,超限转人工队列 | 无限重试把下游打得更死 |
| 顺序 | 逆序补偿,并核对业务依赖 | 先退券后关单,客户仍在使用优惠 |
| 审计 | 正向与补偿记录成对留存,可对账解释 | 只有补偿记录,追溯不到原始单据 |
| 不可逆处理 | 已发货、已对外通知等转人工流程 | 系统自动尝试补偿却无法真正撤销 |
补偿动作实现要点
补偿动作实现要点
# 补偿动作示例:释放库存
# 1 幂等:以订单号 + 动作类型作为唯一键,重复调用直接返回成功
# 2 前置校验:确认该订单确实处于已锁定状态,避免误释放
# 3 分离重试:区分可重试(下游超时)与不可重试(数据非法)
# 4 记录:写入补偿流水,包含原因、次数、来源请求 ID
# 5 上限:超过重试上限进入人工队列并告警,不静默丢弃
# 6 对账:每日比对锁定与释放记录,差异条目自动列出待处理补偿不是撤销:它产生新的业务事实,审计与对账必须能解释两条记录的关系,否则账目看起来是重复入账或凭空冲销。
不可补偿的场景必须提前识别(已发货、已通知外部机构、已消耗的权益),为它们设计人工介入流程,而不是让系统反复重试。