知识全景图/ 软件工程与系统/ 失败处理与业务一致性

失败处理与业务一致性:补偿、对账与回放

回答“订单、审批、支付、账务、消息和同步出错后,系统如何发现差异、补正状态并可控重放”

阅读边界: 这页不是单讲分布式事务模式,也不是只讲财务对账;它把幂等、补偿事务、对账任务、消息重试、事件回放和人工修复放成一套业务一致性恢复能力。

一句话判断: 如果系统只设计了成功路径,没有设计失败后的对账、补偿和回放,它就不是真正可运营的跨系统业务。
路线定位:它解决失败后的业务状态不乱
不解决什么真正解决什么适合出现在哪里
不替代系统边界设计边界已经存在后,处理跨系统动作失败、重复、延迟和部分成功。接口、事件、数据和权限设计之后。
不等同于强一致事务在无法用单个事务包住的业务链路里,让状态最终可发现、可解释、可修复。支付、审批、订单、账务、物流、消息、数据同步。
不只是运维补救提前设计幂等、对账、补偿、回放和人工接管,避免事故时临时脚本救火。架构设计和上线评审阶段就要检查。
一、它真正解决什么问题
失败可被发现 操作可幂等 差异可对账 状态可补偿 事件可回放 影响可审计
场景风险治理判断
支付 / 账务外部支付成功但内部订单失败,或账务分录缺失支付结果、业务状态和账务凭证必须可对账、可追补
消息重试重复消费、乱序消费或消息永久堆积先设计幂等键、去重表和死信处理,再谈重试次数
异步任务任务部分成功,状态停在中间态中间态要有超时扫描、补偿动作和人工接管入口
事件回放回放触发二次副作用或污染当前状态回放必须区分历史重建、补发通知和真实业务动作
二、关键机制
幂等设计
幂等不是“多试几次没事”,而是每类外部动作都有业务幂等键、状态机和去重记录。
补偿事务
补偿不是简单反向 SQL,而是按业务语义定义撤销、冲正、补发、关闭或人工处理。
对账任务
对账要有权威来源、差异分类、容忍窗口、处理优先级和闭环状态。
死信与隔离
无法自动处理的消息要隔离、告警、可查询、可修复,而不是无限重试拖垮系统。
事件回放
回放前要定义范围、版本、幂等策略、速率限制和副作用开关。
人工运营入口
高风险修复需要审批、dry-run、审计和回滚方案,不能靠临时脚本隐身操作。
三、失败类型分类
失败类型表面现象优先使用的恢复能力
外部成功、内部失败支付、物流、短信等外部动作已成功,但本地状态未推进对账发现差异,按业务语义补偿推进本地状态或发起反向动作
内部成功、外部未知本地已提交,但外部调用超时,无法确认真实结果查询外部权威结果,避免盲目重试造成重复扣款或重复发货
消息重复、乱序或丢失消费者多次收到同一事件,或先收到后置事件幂等键、状态前置条件、去重表、死信队列和回放补齐
历史逻辑错误一段时间内事件处理逻辑有 bug,当前状态或报表存在系统性偏差冻结范围,修正逻辑版本,使用事件回放或批量补算恢复
人工修复引入新差异临时 SQL 修了一个系统,却让账务、缓存或下游报表继续不一致把人工修复纳入对账闭环,并要求复核所有受影响系统
四、幂等、补偿、对账、回放怎么配合
能力它负责什么不能替代什么
幂等保证重复请求、重复消息、重复执行不会造成二次副作用不能发现漏处理和跨系统差异,所以还需要对账
补偿在部分成功或状态卡住时,用业务语义推进、撤销、冲正或关闭不能简单等同于反向 SQL,尤其账务和外部动作必须按业务规则处理
对账周期性比较权威源、业务状态、账务凭证和外部结果,发现差异不能只产出报表,必须连接自动补偿或人工处理队列
回放用历史事件或任务重新构造缺失状态、修复处理漏洞或重建读模型不能直接走有外部副作用的生产路径,必须隔离通知、扣款、发货等动作
人工修复处理自动规则无法覆盖的异常样本和高风险个案不能绕过审批、dry-run、审计和修复后对账
五、场景路线:订单、账务、消息
订单链路
先设计订单状态机和超时扫描,再处理支付结果、库存锁定、履约通知和取消补偿,避免状态停在“处理中”。
账务链路
以账务流水和凭证为权威线索,使用冲正、补记、红蓝字或调整分录,不用普通状态更新代替账务语义。
消息链路
生产端有 outbox 或事件表,消费端有幂等键、去重窗口、死信入口和重放批次,避免“消息发了就算成功”。
迁移链路
迁移期间要并行跑新旧结果对账,出现差异先分类再补偿,不要靠一次性切流赌正确性。
六、常见误区
误区为什么危险修正方式
把 MQ 当成可靠性答案消息投递成功不代表业务处理成功对业务状态、外部结果和消费结果分别建账
用重试掩盖幂等缺失重复扣款、重复发货、重复通知都会被放大所有可重试动作先有幂等键和状态判断
回放时直接跑生产逻辑历史事件可能触发邮件、扣款、库存等真实副作用回放路径要有副作用隔离和版本适配
七、上线 / 治理检查项
检查项最低要求
幂等键关键写动作、外部调用、消息消费都有幂等键和去重窗口
状态机中间态、终态、失败态、可补偿态和人工介入态清晰
对账口径清楚权威来源、对账频率、差异分类和处理 SLA
回放保护回放范围、速率、版本、幂等和副作用开关明确
审计闭环补偿和人工修复有审批、执行记录、影响对象和复核结果
八、补偿登记卡、对账证据与回放门禁
补偿登记字段要写清楚什么缺失后的风险
补偿对象业务单号、外部结果、内部状态、账务凭证、消息 ID 和 owner,明确这次补的是哪一笔、哪一段链路只知道“有异常”,不知道应该推进订单、补账、补消息还是交给人工处理
触发条件超时、对账差异、死信、状态卡住、人工确认等触发来源,以及自动触发还是人工审批触发补偿规则变成隐形经验,事故后无法解释为什么某批对象被处理
业务语义推进、撤销、冲正、补发、关闭、人工处理等动作含义,不能只写反向 SQL 或状态覆盖技术动作看似成功,业务语义却错了,例如该退款的单被直接标完成
幂等与副作用幂等键、去重窗口、外部动作是否会重复,以及通知、扣款、发货等副作用如何隔离补偿本身制造二次扣款、二次发货、重复通知或重复账务分录
审计与复核执行记录、影响对象、审批人、对账结果、业务确认和后续 owner修完后无法证明影响范围,也无法证明差异已经闭环
回放门禁必须满足什么失败时动作
范围冻结事件范围、时间窗、处理版本、目标对象和非目标对象都被明确冻结暂停回放,先产出对象清单和排除清单,避免误伤正常数据
副作用隔离通知、扣款、发货、外部调用不能被真实触发,或必须切到 mock / dry-run / outbox 隔离路径立即停止批次,检查外部副作用是否已经发生,并进入事故处理
速率与水位限速、队列水位、下游承载、暂停条件和回退批次策略清楚降速或暂停,先保护下游稳定性,再继续处理差异
结果校验差异清单、对账口径、抽样验证、回放前后指标和异常样本留痕不得扩大批次,先解释差异变化和新异常来源
退出条件差异归零,或剩余差异都有 owner、处理队列、复核日期和业务接受结论不能宣告完成,只能标记为待人工闭环或继续补偿
九、典型生产场景与最小落地包
场景最小落地包验收信号
支付成功但订单未完成建立支付结果表、订单状态对账任务、补偿动作和人工介入队列;补偿必须按业务语义推进状态,不直接改终态每笔外部成功支付都能落到完成、退款、关闭或人工处理之一
消息重复或乱序消费为消费动作定义业务幂等键、去重窗口、状态前置条件和死信处理入口重复消息不会产生二次扣款、二次发货或二次通知
历史事件需要回放先冻结回放范围、事件版本、副作用开关、限速和结果校验,再分批重放回放能修复缺口,不触发真实外部副作用,差异清单逐步归零
十、和现有图谱怎么互链
相关页连接关系
支付 / 账务账务类系统最需要补偿、冲正、对账和审计闭环
业务数据库事务、幂等与并发一致性单库内的重复提交、唯一约束、乐观锁、状态前置条件和事务边界应先在业务数据库层守住
消息队列 / 事件驱动补偿和回放是异步架构从可用到可信的关键治理层
数据契约回放和对账依赖稳定的事件语义、版本和字段兼容
生产数据修复与运维操作自动补偿处理不了的差异,会进入生产修复治理
数据库生产数据修复、人工变更与安全操作当差异最终需要落到生产数据库定向修复时,要按候选主键、可信旧值、dry-run、分批执行和派生副本复核处理
迁移工程迁移期间需要对账和回放证明新旧链路一致