用户当天短信配额 50 条,调发送接口后库存不足抛异常,订单回滚,短信没发出去。配额表里 used 从 12 变成 13,连续 5 次失败后配额被扣到 45,用户第二天投诉额度不对。碰到这种情况,我一般先确认改动有没有真的生效。

原因不复杂,配额扣减先于业务事务执行,走的是另一条 SQL 或者独立的 Redis 命令,业务回滚管不到它。扣减没有补偿逻辑,失败路径上没人把额度加回来。

「配额与事务不一致」这类改动最怕改一半,回滚脚本先准备好,再动生产。日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。

SELECT user_id, total, used FROM quota WHERE user_id = 3312;
UPDATE quota SET used = used - 1 WHERE user_id = 3312 AND used > 0;
-- 对账:成功单量应与 used 相等

权限不要一口气开到最大,先加到够用再往上试,范围小才好收。

具体做法是,配额扣减挂在业务事务里 同一个数据源一起提交;用 Redis 的把扣减放到事务提交之后 通过事件触发;失败路径补一个退款动作 按 traceId 幂等。

最后用这个标准收尾,模拟 5 次下单失败后 used 仍是 12,成功下单时 used 每次稳定加 1。

作者 9823189