「扣减库存」的方案设计

本文探讨了扣减库存的三种方案,包括下单即减、付款确认减和预扣库存,以及应对恶意买家和高并发场景的措施。重点介绍了限制用户下单、使用人工智能识别、数据库事务锁定库存等方法,以及在秒杀场景中的应用和并发控制技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、扣减库存的三种方案

1.1 下单减库存

用户下单时减库存

优点:实时减库存,避免付款时因库存不足减库存的问题

缺点:恶意买家大量下单,将库存用完,但是不付款,真正想买的人买不到

 1.2 付款减库存

下单页面显示最新的库存,下单时不会立即减库存,而是等到支付时才会减库存。

优点:防止恶意买家大量下单用光库存,避免下单减库存的缺点

缺点:下单页面显示的库存数可能不是最新的库存数,而库存数用完后,下单页面的库存数没有刷新,出现下单数超过库存数,若支付的订单数超过库存数,则会出现支付失败。

 1.3 预扣库存

下单页面显示最新的库存,下单后保留这个库存一段时间(比如10分钟),超过保留时间后,库存释放。若保留时间过后再支付,如果没有库存,则支付失败。

优点:结合下单减库存的优点,实时减库存,且缓解恶意买家大量下单的问题,保留时间内未支付,则释放库存。

缺点:保留时间内,恶意买家大量下单将库存用完。并发量很高的时候,依然会出现下单数超过库存数。

二、如何解决恶意买家下单的问题

这里的恶意买家指短时间内大量下单,将库存用完的买家。

2.1 限制用户下单数量

优点:限制恶意买家下单

缺点:用户想要多买几件,被限制了,会降低销售量

 2.2 标识恶意买家

 

通过标识用户的设备 id 或者会员 id,将用户加入黑名单,不足之处是有些用户是模拟的,识别不出来是不是真正的恶意买家。 

2.3 人工智能

用人力解决此事情。曾经在TM上面买了几件衣服,当时觉得贵,下了订单但是没有支付。第二天就有店家打电话过来询问是否支付过程遇到什么麻烦?我回答:价格比较贵,等到双11之后看看有没有优惠。 店家也回答:我们新款服装不打折。最后,店家后台取消订单。

反思:下单即锁定库存,别人不能购买,影响店主售卖衣服。

三、如何解决下单成功而支付失败(库存不足)的问题

3.1 备用库存

商品库存用完后,如果还有用户支付,直接扣减备用库存。

优点:缓解部分用户支付失败的问题。

缺点:备用库存只能缓解问题,不能从根本上解决问题。另外备用库存针对普通商品可以,针对特殊商品这种库存少的,备用库存量也不会很大,还是会出现大量用户下单成功却因库存不足而支付失败的问题。

四、如何解决高并发下库存超卖的场景

库存超卖最简单的解释就是多成交了订单而发不了货。

场景

用户 A 和 B 成功下单,在支付时扣减库存,当前库存数为 10。因 A 和 B 查询库存时,都还有库存数,所以 A 和 B 都可以付款。

 A 和 B 同时支付,A 和 B 支付完成后,可以看做两个请求回调后台系统扣减库存,有两个线程处理请求,两个线程查询出来的库存数 inventory = 10

然后 A 线程更新最终库存数 lastInventory = inventory - 1 = 9,

B 线程更新库存数 lastInventory = inventory - 1 = 9。

而实际最终的库存应是 8 才对,这样就出现库存超卖的情况,而发不出货。

 

那如何解决库存超卖的情况呢

以下方案都是基于数据库层面的。有些同学可能会问,是不是可以用 Redis 分布式锁来,后面会讲到。

 

方案一

SQL语句直接更新库存,而不是先查询出来,然后赋值

UPDATE [库存表] SET 库存数 - 1

 

方案二

SQL语句更新库存时,如果扣减库存后,库存数为负数,直接抛异常,利用事务的原子性进行自动回滚。

 

方案三

利用SQL语句更新库存,防止库存为负数

UPDATE [库存表] SET 库存数 - 1 WHERE 库存数 - 1 > 0

 如果影响条数大于1,则表示扣减库存成功,否则不更新库存,并退款。

 

五、秒杀场景下如何扣减库存

5.1 采用下单减库存

因秒杀场景下,大部分用户都是想直接购买商品的,可以直接用下单减库存。

大量用户和恶意用户都是同时进行的,区别是正常用户会直接购买商品,恶意用户虽然在竞争抢购的名额,但是获取到的资格和普通用户一样,所以下单减库存在秒杀场景下,恶意用户下单并不能造成之前说的缺点。

而且下单直接扣减库存,这个方案更简单,在第一步就扣减库存了。

5.2 Redis 缓存

查询缓存要比查询数据库快,所以将库存数放在缓存中,直接在缓存中扣减库存。

5.3 限流

秒杀场景中,对请求做了很多限流操作,比如前端页面的限流和后端令牌桶限流,真正到扣减库存那一步时,请求数很少了。所以限流常用在秒杀方案中。

一张秒杀场景方案总结:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值