今天我们来探讨下扣减库存的方案。

生活中,我们总是用各种电商 APP 抢购商品,但是库存数是很少的,特别是秒杀场景,商品可能就一件,那如何保证不会出现超卖的情况呢?

一、扣减库存的三种方案

1.1 下单减库存

用户下单时减库存

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

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

1.2 付款减库存

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

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

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

1.3 预扣库存

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

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

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

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

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

2.1 限制用户下单数量

优点:限制恶意买家下单

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

2.2 标识恶意买家

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

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

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 限流

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

另外其实真实的项目中,用到了更多的机制来保证能够正常扣减库存,本篇是抛砖引入,希望大家提出宝贵的建议和方案~。

赠送一张秒杀场景方案总结:

浅析「扣减库存」的方案设计相关推荐

  1. 电商扣减库存_电商系统秒杀架构设计

    作者:曹林华 https://blog.51cto.com/13527416/2085258 前言 最近在部门内部分享了原来在电商业务做秒杀活动的整体思路,大家对这次分享反馈还不错,所以我就简单整理了 ...

  2. [免费专栏] Android安全之静态逆向APK应用浅析「手动注入smali」+「IDA Pro静态分析so文件」+「IDA Pro基础使用讲解」

    也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 Android安全付费专栏长期更新,本篇最新内容请前往: [ ...

  3. 基于redis实现的扣减库存

    2019独角兽企业重金招聘Python工程师标准>>> 在日常开发中有很多地方都有类似扣减库存的操作,比如电商系统中的商品库存,抽奖系统中的奖品库存等. 解决方案 使用mysql数据 ...

  4. 电商扣减库存_电商平台仓库管理系统究竟有何功能?

    仓库管理系统能有效控制并跟踪仓库业务的物流和成本管理全过程,实现完善的企业仓储信息管理.本文介绍了仓库管理的概念,商品与仓库的联系,商品发货的调度中心以及其他附加功能,与大家分享! 仓库管理系统(Wa ...

  5. 电商库存设计mysql redis_基于redis实现的扣减库存

    在日常开发中有很多地方都有类似扣减库存的操作,比如电商系统中的商品库存,抽奖系统中的奖品库存等. 解决方案 使用mysql数据库,使用一个字段来存储库存,每次扣减库存去更新这个字段. 还是使用数据库, ...

  6. 电商扣减库存_竞争激烈的电商市场,小型仓储外包服务解决了中小电商的后顾之忧...

    随着网购消费者要求的提高,以及各大电商巨头向各个领域.品类的扩张,越来越多的中小电商感叹利润微薄,电商生意不好做.但这些并不是中小电商最担心的问题,它们面临的最大问题如何解决符合自身需求的仓储问题? ...

  7. 电商扣减库存_经验分享:电商库存体系设计笔记

    最近在做仓库库存管理相关的项目,清晰地了解了仓库是如何管理库存的,并且整清楚了各个系统的库存是如何交互的,整理了下分享给大家. 库存是什么 这里是百度百科给出的解释: "库存(invento ...

  8. 扣减库存,redis你值得拥有

    扯扯犊子 并发知识点总结: 1.秒杀,物理业务隔离,抽成单独的服务器 2.接口设计,防止洪流访问数据库. 3.加redis缓存. 4.缓存雪崩,一个请求,多个key同时失效,避免同时失效.多个请求,一 ...

  9. java 电商锁库存实现_电商项目扣减库存方案

    阿里巴巴b2b电商算法实战电子商务 85.3元 包邮 (需用券) 去购买 > 各位小宝贝们,大家是不是在面试过程中经常被问到,你电商项目扣减库存时,到底是下单减库存呢?还是付款减库存? 那今天给 ...

最新文章

  1. 李德毅获吴文俊人工智能最高成就奖 | AI日报
  2. Android核心分析 之一分析方法论探讨之设计意图
  3. 怎样实现登录用户管理_如何编写程序实现图书管理系统里面的用户管理功能
  4. OpenCV人脸检测并把图片写成avi视频
  5. 12c oracle 激活_Oracle 12C 安装教程
  6. 通过jsp向mysql批量导入数据_JSP+Servlet+C3P0+Mysql实现的图书馆管理系统
  7. as it exceeds the max of 500KB._我的英雄学院The “Ultra” Stage角色介绍第三弹!
  8. SpringSecurity应用(二)
  9. iOS codeview
  10. 搭建cocos2d-x-android环境 Windows XP3 + Eclipse + NDKR7(或ndkr7b)+COCOS2DX(没有用到cygwin和minigw)...
  11. windows便签快捷键_Windows10便签快捷键在哪里设置?
  12. 全球 40 位 40 岁以下的富豪
  13. 李云龙二次元风格化!
  14. pyecharts学习笔记
  15. 深度学习图片预处理:crop
  16. 完全背包问题 买书(信息学奥赛一本通)
  17. Autonomous Aerial Dual-Target Following Among Obstacles
  18. 删除Github中已有仓库或文件
  19. 企业WiFi安全管家 帮你排忧解难
  20. 洛谷_P2433 【深基1-2】小学数学 N 合一(简单是简单,真的好麻烦!)

热门文章

  1. 让人又爱又恨的Mysql多表查询
  2. 快速解决mongodb出现id重复问题
  3. 学习下ECharts 异步加载数据
  4. 详解 ARM64 内核中对 52 位虚拟地址的支持
  5. 【哈渡谱】带你玩转Hadoop之《CentOS虚拟机安装篇》
  6. 【Java】LeetCode 150. 逆波兰表达式求值 (后缀表达式)
  7. [CQOI2007]涂色PAINT
  8. oracle11g insufficient,ORACLE11GORA-01031:insufficientprivileges
  9. P6271 [湖北省队互测2014]一个人的数论(莫比乌斯反演,拉格朗日插值)
  10. etc下没有mysql_我在linux下,安装mysql的时候,cp support-files/my-medium.cnf /etc/my.cnf找不到my-medium.cnf...