UPDATE wp_gifts SET stock = stock - 1 WHERE id = 12 AND stock > 0;
限量 50 件的保温杯活动结束,兑换记录 63 条,超出的 13 单只能补货或者赔积分。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。
原因不复杂,接口先查库存够不够,再单独执行扣减,两步之间没有事务。并发请求同时读到库存 1,都判断可以兑换。
「积分兑换超发」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。改完隔一天再看一次,当场正常不代表能稳住。
测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。
处理上按这个顺序:库存扣减写成带条件的更新,库存大于 0 才减;受影响行数为 0 就返回已兑完,不再生成订单;礼品和用户加唯一约束,同一人限兑一次;用脚本并发提交 100 个请求压测库存。
改完只确认一件事:压测后兑换记录正好 50 条,库存为 0,没有出现负数。
