解决方案:超卖(Redis队列pop原子性操作)


关键词

  • 不建议使用锁,影响效率
  • redis的leftPushAll(List的长度就是每个商品的库存数)
  • List的长度 是 最准确的库存量

一、实现思路:使用redis的原子队列存储库存列表

1、Redis是单进程单线程的网络模型,用的是epoll网络模型,网络模型都是单线程异步非阻塞处理网络请求

2、Redis的单线程处理所有的客户端连接请求,命令读写请求。(有些任务比如rdb和aof等操作是fork子进程处理的,不会影响redis主线程处理客户端的命令)

3、Redis提供的所有API操作,相对于服务端方面都是one by one执行的,命令是一个接着一个执行的,不存在并行执行的情况


首先我们把库存存在一个列表中,假设有55件库存,就往列表中push55个数,这个数没有实际意义,仅仅只是代表一件库存。抢购开始后,每到来一个用户,就从列表中pop一个数,表示用户抢购成功。当列表为空时,表示已经被抢光了。因为列表的pop操作是原子的,即使有很多用户同时到达,也是依次执行的。

二、实践

1. 使用redis的leftPushAll,将商品库存信息进行存储

//为每个商品维护一个队列List,该List的长度就是每个商品的库存数
//List中存什么不重要,重要的是长度和库存数一致,将每个元素都存储该秒杀商品的id
redisTemplate.boundListOps("商品id").leftPushAll("key","商品id集合")  ;

2. 消费订单(原子性操作:因为列表的pop操作是原子的)

//从redis队列中获取商品的库存队列信息
Object rightPop = redisTemplate.boundListOps("key").rightPop();

3. 获取redis列表的长度=库存量(最准确的库存数)

注意: 此时的队列长度 比 redis中存储的商品的库存属性更精确

/** 库存不精确解决方案:应该获取redis中的真实长度,但是不方便获取,因此可以获取redis队列的长度。内存中的数据不可信*/
//获取到秒杀商品的库存队列,长度就是剩余库存数,最准确的库存数
Long size = redisTemplate.boundListOps("key").size();//当前购买的商品就是最后一件:redis中该商品记录移除
if (size <= 0) {//同步库存数量//将数据同步到Mysql中(库存为0了)//移除Redis中该商品的数据} else {//将库存数据更新到Redis(更新库存递减之后的商品信息) }

解决方案:超卖(Redis原子队列)相关推荐

  1. java的“看门狗”锁续期可以用php redis这样实现【php锁续期、分布式锁、无锁请求队列超卖】解决【商家超卖(商品库存控制)、用户超买(秒杀订单控制)】问题。非demo 线上一直在用

    要求与痛点描述 1.不允许使用库存创建队列 因为库存如果是10w难道要创建一个10w长度的队列吗 2.不允许对整个业务过程加锁 可能业务执行时间很长 导致锁粒度太大 影响并发量 3.如果业务时间大于锁 ...

  2. redis mysql 解决超卖_Redis 分布式锁解决超卖问题

    Redis 分布式锁解决超卖问题 1,Redis 事物介绍 1. Redis 事物是可以一次执行多个命令, 本质是一组命令的集合. 2. 一个事务中的所有命令都会序列化, 按顺序串行化的执行而不会被其 ...

  3. 高并发下防止库存超卖解决方案

    一.概述 目前网上关于防止库存超卖,我没找到可以支持一次购买多件的,都是基于一次只能购买一件做的秒杀方案,但是实际场景中,一般秒杀活动都是支持1-5件的,因此为了补缺,写了此文,方便自己之后使用. 二 ...

  4. redis decr 防止超卖_Redis基础、高级特性与性能调优——一篇文章搞定

    本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍.之后概览Redis提供的高级能力,并在部署.维护.性能调优等多个方面进行更深入的介绍和指导. ...

  5. 电商营销方式抢购,秒杀Redis原子出队列lpop方法作为剩余库存判断条件的实现方式(2)

    秒杀要干的事:正确的减去库存数量,每个库存量正确的对应生成一个订单,买单支付跟秒杀没有关系,秒杀系统是独立的页面,独立的子系统. 1)使用Redis队列保存客户抢购成功的订单编号,使用Redis哈希类 ...

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

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

  7. 秒杀场景下超卖问题解决方案

    秒杀超卖现象:在高并发下,多个线程并发更新库存,导致库存为负的情况. 我搜集了一些资料,整理了一下,秒杀可选方案主要有以下三种: 1.超卖原因 一个简单的订单表 create table orders ...

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

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

  9. Redis高并发场景下秒杀超卖解决

    目录 1 什么是秒杀 2 为什么要防止超卖 3 单体架构常规秒杀 3.1 常规减库存代码 3.2 模拟高并发 3.3 超卖现象 3.4 分析原因 4 简单实现悲观乐观锁解决单体架构超卖 4.1 悲观锁 ...

最新文章

  1. Java业务代表模式
  2. 开发日记-20190828 关键词 读书笔记《Unix环境高级编程(第二版)》DAY 4
  3. replication crash safe
  4. 如何更好的排版介绍性文字
  5. 提升CUDA程序运行效率的几个关键点
  6. 简单了解Vue的异步请求,axios-0.18.0.js插件实现异步
  7. LiveVideoStack线上分享第五季(一):企业视频会议场景下的流量分发和弱网优化...
  8. 笔记本win10玩红警黑屏_【买笔记本电脑差评真的有参考意义?】
  9. mysql评论表结构设计_文章评论嵌套显示mysql表结构如何设计(形式如网易新闻评论)...
  10. 机器学习:分类(Classification)算法
  11. Intent与intent-filter
  12. 怎么彻底卸载cad2017_彻底卸载cad2010的方法步骤
  13. 数据分析—用excel2016和python画箱线图
  14. java简单排序之选择排序(从小到大)
  15. Python:retrying与tenacity模块失败重跑库
  16. amazon alexa simple demo code for libcurl
  17. 【CSS】盒子模型内边距 ① ( 内边距概念 | 内边距设置语法 | 内边距设置效果 | 代码示例 )
  18. springboot使用rocketmq-spring-boot-starter整合RocketMQ
  19. Android(15)——ButterKnife
  20. steam 32位 linux 下载地址,「Linux」- 安装 Steam 客户端

热门文章

  1. 360要在A股上市 华泰联合证券已签订IPO辅导协议
  2. c#自定义控件做漂亮的列表
  3. 内部排序算法系列---快速排序
  4. 现在Windows Server 2012在Windows Azure 虚拟机库中可用
  5. spring中文参考手册-核心技术_ioc
  6. 基于Sanic的微服务基础架构
  7. 流程型企业SCM、ERP、MES、PCS如何集成?
  8. 优秀博客 --敏感词汇过滤
  9. 李洪强iOS开发Swift篇—02_变量和常量
  10. Deep learning:十六(deep networks)