重复入账通常不是“接口被调用了两次”这么简单,而是调用方超时后重试、网络重复投递或并发请求,让同一笔业务被执行多次。防护重点不是阻止重试,而是让同一业务操作无论到达多少次,都只产生一次账务结果。
先定义“同一笔业务”
每次入账都应有稳定、唯一的业务标识,例如来源单据与入账业务共同组成的标识。服务端以它判断请求是否已经处理,不能只依赖每次请求临时生成的标识,否则重试可能被误认为新业务。
同一标识再次到达时,系统应返回已完成操作的结果,而不是再次记账。如果同一标识携带的金额、账户等关键内容与首次请求不同,应拒绝或转入核查,不能悄悄复用旧结果。幂等标识的适用范围也要明确,避免不同业务意外共用。
把判断和入账放在可靠边界内
仅在应用代码里“先查有没有、再写入”存在并发窗口:两个请求可能同时查到未处理,然后都完成入账。应让幂等记录与账务写入通过数据库约束和事务形成可靠边界,使重复请求无法各自提交一笔账。
还要处理“账已入、响应没回来”的情况。调用方会重试,但服务端应识别这仍是原操作,并返回可确认的处理状态。处理中、已完成和失败等状态需要有清晰语义;失败是否可重试,也应与是否已经产生账务副作用相匹配。
如果入账还要调用外部系统,本地幂等并不自动保证外部只执行一次。需要确认对方是否支持幂等处理,并安排状态查询、对账或补偿路径。验收时至少覆盖重复提交、并发提交、超时后重试和外部处理结果不明等场景。可靠的幂等设计不是“请求只来一次”,而是重复请求不会扩大账务影响,且结果最终可核对。