概述
扣减库存方案设计
扣减库存步骤
-
查询库存
-
判断是否超出库存
-
开始扣减
-
付款
第三四步可以互换。
遇到的问题
- 超卖现象
用户 A 和 B 成功下单,在支付时扣减库存,当前库存数为 10。因 A 和 B 查询库存时,都还有库存数,所以 A 和 B 都可以付款。
然后 A 线程更新最终库存数 lastInventory = inventory - 1 = 9,
B 线程更新库存数 lastInventory = inventory - 1 = 9。
而实际最终的库存应是 8 才对,这样就出现库存超卖的情况,而发不出货。
-
恶意买家下单
恶意买家指短时间内大量下单,将库存用完的买家。如果扣减库存后,用户不付款,占用库存名额,但是也要避免某些用户真实需要大量订单。
解决方案
-
使用乐观锁扣减库存
- 利用SQL语句更新库存,防止库存为负数
UPDATE [库存表] SET 库存数 - 1 WHERE 库存数 - 1 > 0
update的锁可以参考:mysql update锁分析 这篇文章了解一下。
-
分布式锁
分布式锁,根据商品编号加锁,去扣减库存。
-
预设库存到redis
秒杀场景提前将库存预设到redis,然后通过redis去扣减,但是要确保原子性(利用lua脚本实现);
- 采用下单减库存
优点:实时减库存,避免付款时因库存不足减库存的问题
缺点:下单扣减库存是会造成恶意买家购买不付款占用库存的问题存在;
- 预减库存
优点:结合下单减库存的优点,实时减库存,且缓解恶意买家大量下单的问题,保留时间内未支付,则释放库存。
缺点:保留时间内,恶意买家大量下单将库存用完。并发量很高的时候,依然会出现下单数超过库存数。
- 付款扣减库存
优点:防止恶意买家大量下单用光库存,避免下单减库存的缺点
缺点:下单页面显示的库存数可能不是最新的库存数,而库存数用完后,下单页面的库存数没有刷新,出现下单数超过库存数,若支付的订单数超过库存数,则会出现支付失败。
- 秒杀扣减并定时人工释放库存
目前直播带货已经非常的火爆了,很多主播上单都是秒清库存的状态,但是也有很多人在直播间只下单不付款,以抖音为例,经常会看到主播让大家抓紧付款,否则就要释放了,由此可见抖音电商使用的就是预减库存,人工可以释放库存的方式。
- 数据库悲观锁控制
为了在事务控制中,防止写覆盖,你会想到使用select for update的方式,将该商品的库存锁住,然后执行余下的操作。
使用悲观锁方式,如果并发情况比较高的时候,扣减库存的操作是串行操作,效率很低。
方案的思路就是:
- 先下单
- 扣减库存
- 如果没有付款,指定时间后自动释放库存
- 如果是秒杀商品,库存被恶意占用,商家可以人工去通知大家,并手动释放没付款的那些库存给没有抢到的人去抢购
- 如果有人恶意占大量库存,也可以设置一个限购数量
结论
各种方案都可以,但是超卖问题必须解决,后续可以根据场景,比如是秒杀,还是直播间,或者普通的购物方式,选择合适的方案。
参考文档:
《扣减库存方案》
《浅析扣减库存的方案设计》
最后
以上就是潇洒棉花糖为你收集整理的完整的扣减库存方案的全部内容,希望文章能够帮你解决完整的扣减库存方案所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复