制造系统里有个经典场景:工人手持终端扫一个箱码,点「生产入库」。那天接口卡了二十多秒,工人以为没点上,又点了一次——两次请求都成功返回,库里多了一模一样的两套库存:库存明细、状态表、入库记录、操作流水,四张表整整齐齐各两行。
代码里明明有查重校验(”当前条码已入库,不可重复入库”),为什么两次都没拦住?这篇文章完整复盘根因链:类级注解把整个入库方法包成一个大事务 → 事务内 MVCC 快照读对并发未提交的插入天然失明 → check-then-act 查重形同虚设 → 生产库唯一索引恰好是普通索引,最后一道兜底也不存在。以及修复方案里一个容易被一笔带过的细节:多条码批量提交时,为什么要按条码排序后依次获取锁才不会死锁。最后附上面试视角的问答拆解——这个问题几乎覆盖了 MVCC、锁、事务、隔离级别的全部高频考点。