下单偶发失败,日志里是 SQLSTATE[23000]: Duplicate entry '20261109143012001' for key 'PRIMARY',一小时出现四次,重试一次又能成功。日志里能对上时间点,这种反而好排。

订单号用年月日时分秒加三位随机数拼出来,同一秒并发下单的请求随机段只有一千种可能,量一上来就撞。号码生成和写库之间也没有唯一性校验。这一点先确认清楚,后面就不用反复试。

INSERT INTO wp_orders (order_no, user_id, amount)
VALUES ('20261109143012001', 9, 299.00);
-- 1062 Duplicate entry 时重新取号重试

这次卡住的地方就在「订单号重复」这一环,单独把它拎出来验证,别和其他改动混在同一次发布里。能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。

处理上按这个顺序:订单号换成带机器位和自增序列的组合,时间戳加分片号加数据库自增,冲突概率降到可忽略;或者直接用自增主键生成,再补一个对外展示的单号,两者分开;写库仍要捕获 1062 错误,命中后重新取号重试一次,别把异常抛给用户。

结果对不对很好判断,压测一千次并发下单,日志里不再出现 1062,订单号长度和格式保持一致。

作者 9823189