库存扣减的"锁"事:拓科技谈悲观锁、乐观锁与分布式锁的选型
一、一个看似简单的问题
“库存扣减”听起来很简单:查库存 → 判断够不够 → 扣减 → 写回。
但在高并发场景下,这个问题变得极其复杂:
- 两个人同时看到库存=1,都去扣减,结果库存变成-1
- 扣减过程中系统崩溃,库存数据不一致
- 分布式环境下,多个服务实例同时操作同一份库存

二、三种锁的对比
洹拓科技在项目实践中,总结了三种锁的适用场景:
2.1 悲观锁
原理:先锁住,再操作。其他线程必须等待。
实现:数据库的SELECT ... FOR UPDATE
优点:简单、安全
缺点:性能差,并发高时大量线程等待
适用场景:并发不高、数据一致性要求极高的场景
2.2 乐观锁
原理:先操作,再检查有没有冲突。有冲突就重试。
实现:版本号机制(UPDATE SET stock = stock - 1, version = version + 1 WHERE id = ? AND version = ?)
优点:性能好,无锁等待
缺点:冲突多时大量重试,可能活锁
适用场景:冲突概率低的场景
2.3 分布式锁
原理:跨多个服务实例的锁,保证同一时刻只有一个实例能操作。
实现:
- Redis:
SETNX+ 过期时间,性能最好 - ZooKeeper:临时有序节点,可靠性高
- etcd:Lease机制,云原生首选
优点:支持分布式场景
缺点:复杂度高,需要考虑锁超时、脑裂等问题
三、洹拓的选型建议
拓科技给客户的选型建议:
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 单机、低并发 | 悲观锁 | 简单可靠 |
| 单机、高并发、冲突少 | 乐观锁 | 性能好 |
| 分布式、中等并发 | Redis分布式锁 | 性能与复杂度平衡 |
| 分布式、高可靠要求 | ZooKeeper/etcd | 强一致性保障 |
四、实战踩坑记录
洹拓科技在项目中踩过的坑:
1. Redis锁超时设置
锁超时太短:业务还没执行完,锁就释放了,其他线程进来造成并发问题。
锁超时太长:持有锁的线程崩溃,其他线程长时间等待。
解决:锁超时设为业务执行时间的2-3倍,加看门狗机制自动续期。
2. 锁的粒度
锁整个库存表:并发度太低。
锁单个SKU:并发度高,但锁数量多。
解决:按业务热点选择锁粒度,热点SKU用细粒度锁,冷门SKU用粗粒度锁。
3. 重试策略
获取锁失败后立即重试:加剧竞争。
等待固定时间重试:可能多个线程同时重试,再次竞争。
解决:随机退避重试,减少碰撞概率。
五、洹拓科技的后端服务
洹拓科技可以为新乡本地企业提供:
- 高并发架构设计:根据业务特点设计合适的并发控制方案
- 分布式系统开发:Redis/ZK/etcd分布式锁的集成与优化
- 性能调优:定位和解决并发性能瓶颈
- 技术培训:培训团队掌握分布式系统开发技能
新乡洹拓科技有限公司,专注后端架构与高并发系统开发,为新乡及辉县本地企业提供分布式系统设计与实施服务。
咨询热线:400-829-9957
地址:河南省新乡市辉县市金城百货四楼