You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

并发下单场景下如何校验库存数量避免超卖问题

库存超卖问题落地方案

优先推荐:乐观锁方案(性能最优,无锁冲突等待)

直接将库存校验和扣减合并为单条原子UPDATE语句,依赖数据库自身的原子操作特性避免并发冲突,无需额外加锁:

  • 核心扣减SQL:UPDATE items SET quantity = quantity - #{buyCount} WHERE id = #{itemId} AND quantity >= #{buyCount};
  • 执行后判断该SQL的影响行数:
    • 影响行数为1:库存扣减成功,继续执行订单插入操作即可
    • 影响行数为0:库存不足,直接返回下单失败
  • 配套要求:将「库存扣减SQL执行+订单表插入」两个操作包裹在同一个事务中,事务隔离级别使用数据库默认的READ COMMITTED即可,无需调整更高隔离级别。
  • 优化点:如果业务存在短时同商品大量下单的场景,可加最多3次的冲突重试机制,提升用户下单成功率。

高冲突场景可选:悲观锁方案(自动排队执行)

如果同商品并发扣减冲突概率极高,乐观锁重试成功率低,可使用行级悲观锁,让同商品的并发下单请求自动排队:

  • 步骤1:开启事务,执行加锁的库存查询SQL:SELECT quantity FROM items WHERE id = #{itemId} FOR UPDATE;
    • 注意:必须确保id字段是索引,否则行锁会升级为表锁,导致全库下单性能雪崩
  • 步骤2:业务层校验库存是否≥下单数量,不足则直接回滚事务返回失败
  • 步骤3:校验通过后执行库存扣减UPDATE、订单插入操作,最后提交事务
  • 特性:同商品的多个并发请求执行到FOR UPDATE语句时,会自动等待前一个持有锁的事务结束后再执行,天然实现后提交的订单等待前一个订单处理完成的需求。

常见疑问解答

  • 不需要锁全表:锁全表会导致所有商品的下单请求串行执行,性能极差,仅用行级锁或者乐观锁即可解决问题
  • 事务是必须的:无论用哪种方案,都需要将库存扣减和订单插入放在同一事务中,避免出现扣了库存没生成订单、或者生成订单没扣库存的数据不一致问题
  • 无需额外调整隔离级别:默认的READ COMMITTED隔离级别已经能满足需求,更高的隔离级别会带来不必要的性能损耗

内容的提问来源于stack exchange,提问作者nikkorfed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 03:24:05