【商城】商城购物车下单库存设计

购物车下单不是一个简单的添加商品然后下单的功能,这背后涉及的内容非常复杂复杂,它与会员系统、商品系统、库存系统、订单系统等紧密结合,设计购物车下单功能时要考虑到与其他系统产生的关联关系,尤其是订单系统、库存系统。在电子商务系统中,订单处理时,优先要考虑的核心的环节就是库存设计,然后围绕库存展开一系列的业务逻辑。那如何减去库存,该在何时减库存就成了首要问题,目前普遍采用的有以下几种方案。

 

常见扣减库存的几种方式分析

    1、放进购物减去库存: “添加进购物车减库存”实际上是“拍下减库存”的衍生出来的新方式,本质上依然是拍下减库存,特点是       将减库存锁定时间缩短,加快了流动速度。唯品会这类特卖网站,一个特卖活动很可能只有3小时,如果还按照淘宝的做法“拍       下后减库存,72小时内不成交,系统才自动关闭交易”,显然不可取,因为整个特卖活动可能也就3小时呀。

特卖的时候大量消费者同一时间涌入,如果消费者拍下后,给很长的思考时间是否购买,特卖根本没法玩,所以得给拍下减       库存增加更敏感的时间限制。

    2、下单减库存:通常采用的都是下单减库存,即当买家提交订单后,在商品的总库存中减去买家购买数量。下单减库存是最简单的、最常用的方式的减库存方式,也是控制最精确、最符合常规逻辑的,下单时可以通过数据库的事务机保证库存的一致性、完整性和正确性严格制控制商品库存,这样基本可以保证一定不会出现超卖的情况。但这样做也有个问题,你要知道有些人下完单可能并不会付款,有些是无意的有些是恶意的,还有些就是想先下单,过一会再买,这“一会”可能是一个小时或几个小时、半天、好几天,还有可能不买了。

拍下减库存的方案无法规避商品恶意被拍的风险。如果商家的商品大量被拍下,但用户一直不付款,就会导致其他真正想买的用户因库存不足而无法下单购买。等到未付款订单到过期时间系统自动取消时,可能会因大量库存被占用而一件商品也没有卖出去。这种事情曾经淘宝真的发生过,前几年淘宝中小商家大闹天猫,狂刷韩都衣舍等大店就是出现了这种的情况,中小商家们疯狂拍下商品,造成韩都衣舍大量商品库存为零被迫下架,导致大量需要正常消费者无法购买。

   3、  付款成功后减库存​​​​​​:即买家下单后,并不立即减库存,而是等到有用户付款后才真正减库存,否则库存不减,视为未购买。就算库存只有一个,其他用户仍然可以继续下单,此方案只将付款订单视为真正的商品订单。但高并发时可能会出现超卖的情况,因为付款时才减库存,并发下单查的时候都是库存充足,尽管三个人买一个库存为1的商品,待三个人都付款成功库存会变为-2,这种超卖情况在促销活动的时候最容易出现。

付款之后减库存,很容易付完钱后,库存不足,因为这个付款的过程可能比较慢,因为要输入密码,调第三方支付之类的。就算发现库存不足后用事务回滚,也行不通:此时买家已经付款了,那么立刻在买家刚刚付过来的钱再退回去吗?这显然是无意义、不可行的。

还有一种情况,就是出现买家下了单却付不了款,因为可能商品已经被其他先付款的人买走了。付款后再减库存这种机制,如果在用户点击支付后,在调起支付之前先去查一下库存,其实也能在很大多数时候上避免超卖的现像,但就怕超高的并发。

 

      4、预扣库存,这种方式相对复杂一些,买家下单后,库存为其保留一定的时间(如 10 分钟),超过这个时间,库存将会自    动释放,释放后其他买家就可以继续购买。在买家付款前,系统会校验该订单的库存是否还有保留:如果没有保留,则再次尝      试   预扣;如果库存不足(也就是预扣失败)则不允许继续付款;如果预扣成功,则完成付款并实际地减去库存。

 

关于未支付订单实效时间和

综合以上来看,第二种下单后扣库存是几个方式中最可行办法之一,只不过我们做一些改进、配合一些机制来解决库存被有意、无意、占用的问题,例如我们可以配合第四种预扣库存的机制。

在用户下单后的若干分钟内如果不进行系统就自动取消用户的订单,释放库存。具体多少分钟这个值可以根据自己实际业务来定。如果未付款订单失效时间太长无法解决库存占用问题,未付款订单失效时间太短会让用户恼火,降低转化率,用户原意本来想购买的只是晚了一些订单就被取消了。
关于订单失效时间这个,我参考了目前最火的三大电商平台的做法:

  • 京东:一般订单都是需要在24小时内支付,否则订单自动取消;抢购活动要在2小时内支付,充值需要在12小时内支付。
  • 拼多多:提交订单后24小时未支付自动取消。
  • 淘宝:未支付订单保存三天的,三天还为支付自动取消,同时商家可以手动取消未付款订单来释放库存,不过这里有小地方需要注意:淘宝商家是可以在后台设置【付款后减库存】or 【下单后减库存】。淘宝普通商品的支付时长是最久的将近3天,平台大,用户量和商家比较多,商品丰富,货比三家,用户可能犹豫时间比较久。

【商城】商城购物车下单库存设计_第1张图片

 

2016年11月,淘宝增加了商品减库存的方式,商家可以自主选择拍下减库存和付款减库存两种方案。

淘宝网一直采用拍下减库存的方式,即用户下单后,商品的线上显示的库存就会减少。但这种方式存在一系列弊端,给买卖双方带来了一定程度的不便。由于用户下单后有72小时的付款时间,在这段时间可能会由于一些原因导致交易取消,这时显示库存的减少会影响其他用户的购买,尤其是一些定量产品。而且采用拍下减库存的方案无法规避商品恶意被拍的风险。如果商家的商品大量被拍下,但一直未付款,造成其他用户无法购买,就会给商家造成经营上的损失。

为解决和规避存在的问题,淘宝网增加了付款减库这一方案。付款减库存即买家提交订单付款以后,商家商品显示的库存数量才会相应减少。但选择付款减库存也存在一定风险:如果选择付款减库存的方式,在商品促销或者有买家同时购买时会出现超卖情况。淘宝网表示,超卖的订单需和用户协商好补货或者退款,如果因超卖问题用户发起投诉,建议买卖双方自行协商处理,投诉做完结处理。

  我们可以设计的灵活一点,在库存紧张的时候把未付款订单失效时间缩短,在库存充足的时候把未付款订单失效时间延长长,   以弹性的机制来缓解商品库存问题,还可以对未付款的订单进行库存紧张支付提醒:

1)用户未在线:

提醒时间:一出现库存紧张就提醒 

提醒文案:"库存告急,请及时支付“(具体运营优化)

提醒方式:短信和消息推送

 2)普在用户在线的情况时以每分 

提醒时间 :30分钟,60分钟两个时间段 (后期有用户行为数据在具体分析提醒时间的策略)

提醒文案:还有xx分钟,交易即将关闭,请及时支付 (具体文案运营优化)

 

那用下单减库存+未付款订单在若干小时、指定时间内失效的方法,如何应对在库存紧张的情况下并发下单这样的应用场景呢,倘若10个人同时下单购买一个库存只有3个的商品,程序该如何设计?

 下单减库存”在数据一致性上,主要就是保证大并发请求时库存数据不能为负数,也就是要保证数据库中的库存字段值不能为负数,一般我们有多种解决方案:一种是在应用程序中通过事务来判断,即保证减后库存不能为负数,否则就回滚;另一种办法是直接设置数据库的字段数据为无符号整数,这样减后库存字段值小于零时会直接执行 SQL 语句来报错;再有一种就是使用 CASE WHEN 判断语句,例如这样的 SQL 语句:

UPDATE item SET inventory = CASE WHEN inventory >= xxx THEN inventory-xxx ELSE inventory END

   在交易环节中,“库存”是个关键数据,也是个热点数据,因为交易的各个环节中都可能涉及对库存的查询,我们可以把库存放在redis缓存中,因为redis是非关系型内存数据库,所以Redis的读写能力远胜于任何关系型数据库,因此在Redis中保存商品库存数据并完成扣减操作。

还有就是用队列来处理并发下单。

 

还有一个经常遇见的应用场景:如果有一个商品被很多人下单却未付款,占着库存,此时库存很十分的低又有大量的用户涌进来要购买,而占着库存的那一批人他们的订单又未达到系统设定的失效时间,那该怎么办?

此时就真正遇到了上面提到的库存占用问题,我们可以应用以下几种方案,或则结合来用:

库存量低时,大幅度缩短未付款订单有效时间,及时地时间及时释放库存,商家也可以手动取消很长时间未付款的用户订单,把库存让给急等着购买的用户。

应用虚拟库存概念,将超过n分钟未付款的订单为视为潜在库存,在其他用户下单时直接剥夺超过n分钟未付款的订单库存,当然,如果其他用户下单也长时间未付款的话,同样会被列为“潜在库存”的行列。这就需要我们每次都在订单列表查一下库存,如果之后库存补上了,他的订单会被自然的为正常订单,可正常付款,订单上一切东西不变。

 虚拟库存的概念看上去和付款后减库存有点像,实际上和付款后减库存这种方式相差甚远 ,它结合了下单减去库存的方案和预扣库存 又配合他的一些调度策略和超限机制来完成业务需要,同时保证库存数据的一致性和正确性。又加入了许多条件,达到既定的某些条件才能触发这个应急机制。
只有达到条件才会启用,在库存紧缺而购买这个商品的人数非常多的时候、且下单后超过N分钟未付款才会触发这个机制,主要是看购买和人数和商品库存的比例。且如果库存补上后,会自动弃用这套机制,走正常流程。 

虚拟库存比付款后减库存要更加复杂、智能与灵活,实现了随机应变,它它结合了下单减去库存的方案和预扣库存 又配合他的一些调度策略和超限机制来完成业务需要,程序根据当前的场景变化自动调整减库存机制、切换应对策略,使程序更具前瞻性和预见性,其实就是我们为设想到的极限应用场景预留了一套备用扣库存机制。简单的说就是在特殊情况下把某些超过一定时间未付款的订单转为库存,或者说视为库存

 

虚拟库存在电商领域的应用(延伸阅读)

虚拟库存 > 实际库存:卖家做促销活动时,面向消费者显示的库存实际上并不存在,或数量上远大于卖家的库存。卖家可以集中超额部分的订单向供应商要货,向供应商议价,能做到先卖货再进货,降低成本。同时集中运输,降低物流成本。

虚拟库存 < 实际实库:买家易生抢购心理,促进买家下单。在某品类的商品中,虚拟库存也为卖家提供涨价的机会,如茅台、红酒。某些酒品类商品会随时间的推移而涨价,能提高利润。虚拟库存是用来卖货的,实际库存是用来盘货的。

在实际应用中, 淘宝的某些店铺也是这么做的,我们经常会遇到拍下某个商品后没付款,第二天去付款的时候订单变灰色,提示库存不足,等过几天你再去看的时候你又可以发起罚款了,因为库存补上来了。还有就是即使你付了款,商家依然没货依然没关系,因为有一个承诺发货时间,商家可以利用这几天来调货、补货。

 其实在电商领域还有另一种虚拟库存的概念,电商卖家行业一般称为“搬货”,指的通过电商oa软件把别人店铺的商品上到自己店铺,价格标的比原价高一点,当有人下单时再去原商品店铺去下单,也就是上家,这就是传说中的无货源模式。

当然上面有点扯远了,这篇文章主要探讨了极端环境下如何保证库存数据的一致性和完整性、正确性,解决问题的思路和解决问题思维至关重要,它会引领你找到任何问题的解决方案。

你可能感兴趣的:(程序设计,架构,思考)