SELECT step_no, action, status, compensated FROM saga_action_log WHERE saga_id = 'SG20260301001' ORDER BY step_no DESC;
下单链路走 Saga 编排,第二步锁优惠券抛了 TimeoutException,订单表状态是 FAILED,库存表那条扣减记录还在,goods_id 8812 少了 2 件。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。
追下去是这么回事:编排器捕获异常后只把当前步骤标成失败,没有按反向顺序调用已完成步骤的 compensate 接口。步骤记录里 compensated 字段一直是 0,补偿分支根本没有进过。
「Saga 回滚」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。权限不要一口气开到最大,先加到够用再往上试,范围小才好收。
把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。
处理上按这个顺序:按全局事务号把已成功步骤按完成时间倒序列出来;从最后一步开始逐个调用 compensate 接口;补偿结果也要落库 成功才置 compensated=1;给整条 Saga 设总超时 超时统一走补偿分支。
确认没问题再收工,saga_action_log 里每个成功步骤的 compensated 都是 1 库存表对应 goods_id 的数量回到扣减前。
