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

微服务与数据库并发锁问题:单库存物品同时请求锁的处理方式

微服务场景下单库存并发请求的处理方案

你提到的这种「单库存+同时请求」的边缘场景,核心问题是跨服务/跨实例的锁竞争——单进程的线程锁(比如Java的synchronized)只能管单个服务实例内的线程,没法覆盖多实例部署的微服务架构。下面是几种落地性极强的解决方案:

1. 分布式锁(通用首选方案)

用Redis、ZooKeeper这类分布式中间件实现全局锁,保证同一时间只有一个服务实例能操作库存:

  • 核心逻辑:处理请求前,向Redis发起原子性的锁请求,比如执行SETNX lock:stock:1001 "uuid" EX 10(EX 10是加10秒过期时间,防止服务挂了锁一直占用)
  • 拿到锁的实例:执行扣减库存、生成订单等业务逻辑,完成后用Lua脚本原子释放锁(避免误删其他实例的锁)
  • 没拿到锁的实例:直接返回「商品已售罄」或引导用户稍后重试,别让用户长时间等待
  • 避坑点:必须加锁过期时间,释放锁一定要用原子操作(别直接DEL,先判断锁的归属)

2. 数据库乐观锁(轻量无依赖方案)

不用额外中间件,直接利用数据库的原子更新特性,适合中小团队或并发量不算极高的场景:

  • 基础版SQL:UPDATE inventory SET stock = stock - 1 WHERE id = ? AND stock > 0,执行后检查影响行数,若为0说明库存已被其他请求扣减,直接返回失败
  • 进阶版(解决ABA问题):给库存表加version字段,执行UPDATE inventory SET stock = stock -1, version = version +1 WHERE id = ? AND version = ? AND stock > 0,每次更新都校验版本号
  • 优势:不用引入新组件,运维成本低;缺点:高并发下会有较多请求失败,要配合前端友好提示(比如「手慢了,商品已售罄」)

3. 业务层面兜底(降低并发压力)

在锁机制之外,从业务流程上减少无效请求:

  • 前端限流:商品详情页实时同步库存状态,库存为0时置灰购买按钮;点击购买后加loading,防止用户重复提交
  • 服务端双重校验:处理请求前先查缓存+DB的库存值,若已为0直接返回售罄,再走锁/乐观锁逻辑,减少无效的锁竞争
  • 串行化处理:把购买请求放进MQ(比如RabbitMQ),用排他队列保证请求串行执行,只有第一个请求能处理库存,后续请求直接返回失败

新手必避的坑

  • 别用单进程线程锁:微服务多实例部署时,synchronized、ReentrantLock这类锁完全没用,每个实例都有自己的锁,管不了其他实例
  • 别用数据库悲观锁:比如SELECT FOR UPDATE,高并发下会导致大量线程阻塞,直接拖垮数据库
  • 分布式锁别忘过期时间:如果服务在持有锁时崩溃,没过期的锁会永远占用,导致后续请求都拿不到锁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 20:42:35