一、描述:

商城设计的过程中,必然会考虑到一个库存扣除的问题,超卖将会带来一定的损失和麻烦,在某一个时间段的瞬间的流量会造成库存的并发性操作带来库存超额扣除。针对这类的问题,我先来分析原因吧。

二、为什么会被超卖

只有弄清楚为什么会被超卖才能解决超卖问题,这里我们要弄清楚mysql的默认的扣除方式,update 表 store=store-1 where id=指定的id
首先我们看这样的语句有哪些问题呢?

  1. 库存有可能扣到为负数,无法锁定最后的库存
  2. 如果从外面select一次库存,再查找又怕出现主从不一致问题
  3. 并发问题

如何解决以下问题呢?

三、解决方案

1、采用redis队列的方式进行库存增减运算。将创建订单、退款、取消订单做list的相应的增减操作

(1)创建商品、变更数量

  初始化redis的list结构,变更商品数量的时候,redis的list数量做相应的增减。

(2)商品上架、下架

 下架:设置redis的list过期上架:初始化redis的list

(3)创建订单成功

  list进行出队列的lpop

(4)取消订单、退款

  list的lpush入队列,进行补偿

(5)库存校验

 判断list的数量-当前的购买的数量 > 0的情况否则:提示库存不足

这种方案,看起来很完美,没啥问题,细心下你会发现,假如一些用户进入队列后,他不想买了,停在页面时间较长,这个就比较不好处理了,直接性导致很多刃余库存无法释放,估计还得写lua来控制了,比较得不偿失。

2、 锁定最后库存+乐观锁

系统中通过事务来判断,保证扣减后数据不为负数,否则回滚

设置数据库字段数据为无符号证书,通过扣减是,字段值小于零触发sql语句报错

select id,store,status,version from 商品表 where id=#1 and status=1,读出库存以及版本

修改库存:update 商品表 set store=store-#1,version=version+1 where status=1 and version=#version and store - #1 》 0

读取库存和版本信息的时候可强行读主库,避免主从不一致的情况,版本信息,

判断:库存-num > 0,版本=当前版本,避免延迟。

缺点:这种方案也是网上最多的方案,看起来很完美的,实际上也是有缺陷的,假如你的接口事务开始到事务结束,所需的时间是200ms,在这个200ms内的所有并发操作,只有一个人是成功的,其它用户因为乐观锁的原因都是失败的。当日了这个是针对并发量较大的情况才会发生的,一般的小流量倒是可以对付的。

3、 锁定最后库存无乐观锁

系统中通过事务来判断,保证扣减后数据不为负数,否则回滚
反正我不管最终update多少次,只要扣除成功了就行。也就是说我守住最后的底线,这种情况就不会出现一个人成功,其他人都失败的情况。事务过程中实际也是刷新脏页的过程,这种过程主库的update操作实际都是内部有个排队机制的,不会出现超卖的现象。
update 商品表 set store=store-#1 where status=1 and store - #1 》 0

个人认为3方案更加人性化一些,也比较简单,不需要读取过多的信息
1方案成本较高一些,当然了大型项目比较适合
2方案比较严谨一些,避免出现问题的几率较大,大型公司的mysql服务器在这个中间事务开始到操作结束,10ms不到,这种情况下一人成功,其他人失败问题不大。

商城超卖问题的几种解决方案相关推荐

  1. 解决秒杀系统超卖问题的三种方案

    在秒杀系统设计中,超卖是一个经典.常见的问题,任何商品都会有数量上限,如何避免成功下订单买到商品的人数不超过商品数量的上限,这是每个抢购活动都要面临的难点. 一.问题描述 在多个用户同时发起对同一个商 ...

  2. MySql(15)——Mysql在高并发情况下,防止库存超卖而小于0的解决方案

    本人上次做申领campaign的PHP后台时,因为项目上线后某些时段同时申领的人过多,导致一些专柜的存货为负数(<0),还好并发量不是特别大,只存在于小部分专柜而且一般都是-1的状况,没有造成特 ...

  3. Mysql在高并发情况下,防止库存超卖而小于0的解决方案

    背景: 本人上次做申领campaign的PHP后台时,因为项目上线后某些时段同时申领的人过多,导致一些专柜的存货为负数(<0),还好并发量不是特别大,只存在于小部分专柜而且一般都是-1的状况,没 ...

  4. 淘宝如何解决超卖问题

    这篇文章是我从某文库爬下来的,放在这里供大家学习. 淘宝超卖现象的产生及解决方案 一.什么是超卖现象?  超卖即"超卖缺货",当宝贝库存接近0时,如果多个买家同时付款购买此宝贝,将 ...

  5. 电商中怎么防止超卖问题

    首先我们要知道超卖的原因是什么:超卖的原因主要是用户下的订单的数目和我们要促销的商品的数目不一致导致的,每次总是订单的数比我们的促销商品的数目要多.究其深层原因,是因为数据库底层的写操作和读操作可以同 ...

  6. 解决高并发的问题python_python ---解决高并发超卖问题

    使用redis 解决美多商城超卖的问题 import redis r = redis.Redis(host='localhost', port=6379) #定义过载 def limit_handle ...

  7. kdj超卖_kdj超卖是什么意思,kdi超卖的部分使用技巧

    我们之前曾经多次介绍过股票盘中的不同类型指标,比如之前的文章中我们讲解MACD指标买点怎么回事.obv指标什么意思.ROC指标怎么用等等,这些如果你有兴趣的话可以点击查看.而今天我们在本篇文章中要介绍 ...

  8. 大型API网关(八)—— 超卖和资源隔离

    超卖 1. 例子 先举个超卖的例子,解释一下什么是超卖. 小高去某运营商办了宽带,100M的,很兴奋,想着看视频肯定不卡了.结果到了晚上,刷视频时,又卡成狗. 第二天白天就又变好了,这是咋回事呢? 聪 ...

  9. 分布式商城系统架构中的超卖问题深度剖析(从问题原因到解决方案到优化总结)以及重复下单问题

    超卖问题(包含重复下单问题) 背景 首先,超卖问题的出现是由于高并发环境下,大量秒杀请求同时发给服务端导致的秒杀商品的销售数量>其库存数量的问题.其本质就是并发场景下,多线程或者多进程对共享资源 ...

  10. 秒杀超卖 解决方案(史上最全)

    文章很长,建议收藏起来慢慢读!疯狂创客圈总目录 语雀版 | 总目录 码云版| 总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 经典图书:<Java高并发核心编程(卷1)> 面试必备 ...

最新文章

  1. python爬虫不错的文章
  2. SQL语言之序列(Oracle)
  3. 【Linux部署】【elasticsearch-6.4.3 单机版】【不能以root用户运行es 及 max_map_count 问题解决】(含 安装包+分词插件 云盘资源)
  4. 编程题走迷宫_C++程序算法题----迷宫(一)
  5. 服务器c盘windows文件夹太大,Win10C盘windows文件夹过大怎么办?Win10C盘windows文件夹过大的解决方法...
  6. ASP.NET刷新页面的六种方法(转) 包括在跳转的时候使用提示
  7. 双向箭头轮播图html,swiper轮播图配合nextTick的使用
  8. mysql 核心笔记 逻辑符号 like
  9. spring相关技术实现的核心原理
  10. 前端js导出excel代码及出现的中文乱码和数字过长等问题的解决办法
  11. 数据结构:链队列的基本操作(C语言实现)
  12. php 图片上加文字,PHP语言之给图片添加文字(支持中文)//PHP函数
  13. tp6多表联合查询的几种方式(模糊搜索+分页+字段限制)
  14. 计算机无法从硬盘启动怎么办,电脑开机无法引导硬盘启动怎么解决
  15. bae java mysql_在百度bae云平台中使用JAVA连接MySQL数据库
  16. 技术狂潮下的生理性健忘:科技产品如何影响我们的大脑?
  17. HDU - 4322
  18. 大数据商机VS个人隐私 车联网的攻与守
  19. OnDraw()和OnPaint()
  20. 揭示世界本质的「机器科学家」,比深度神经网络还强?

热门文章

  1. PHP服务端 苹果支付(IAP)处理
  2. 脚踩智能汽车春风,百度踏上千亿美元市值征程
  3. 博客文章详情页更新公告
  4. 下行L1/L2控制信道
  5. 黑龙江省大学计算机学校排名2015,2015黑龙江省最佳大学排行榜
  6. 小米3流量显示无服务器,因为小米3元不限流量卡,我尝到了无网可用的滋味
  7. 年薪90万的阿里p7和副处级干部选哪个?
  8. 对往届软件工程的思考——写在软件工程开课之际 by 姜健
  9. 三个div怎么分别靠左、居中、靠右显示
  10. Local package.json exists, but node_modules missing, did you mean to install?