UPDATE stock SET qty = qty - 1 WHERE sku_id = 1001 AND qty >= 1; -- 检查 affected_rows
大促时同一商品卖出数量超过库存,日志里多个请求都判断为有货。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。
原因不复杂,查询与扣减分两步执行,中间没有原子约束,并发时都读到相同余量。
这次卡住的地方就在「库存超卖控制」这一环,单独把它拎出来验证,别和其他改动混在同一次发布里。备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。
接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。偶发问题先统计频率,一小时几次和一天一次,查法完全不同。
改完顺手把文档补一句,省得下次自己重新推一遍。监控和日志的时间要对上,时区不一致会多绕很大一圈。
处理上按这个顺序:用条件更新保证原子性;影响行数为 0 视为失败;高冲突场景再考虑悲观锁。
改完只确认一件事:压测后库存与订单数量一致,没有再出现负数或超卖。