Redis优惠券秒杀超卖问题

Redis秒杀超卖问题

  • 前言
  • 一、出现秒杀超卖的原因
  • 二、超卖解决方案
    • 使用乐观锁解决超卖问题
    • 程序中进行解决


前言

这是我认为b站上最好的redis教程,各方面讲解透彻,知识点覆盖比较全。
黑马redis视频链接:B站黑马redis教学视频
本文参考黑马redis课程笔记


一、出现秒杀超卖的原因

超卖问题分析:
在我们原有代码中是这么写的

 if (voucher.getStock() < 1) {// 库存不足return Result.fail("库存不足!");}//5,扣减库存boolean success = seckillVoucherService.update().setSql("stock= stock -1").eq("voucher_id", voucherId).update();if (!success) {//扣减库存return Result.fail("库存不足!");}

假设线程1过来查询库存,判断出来库存大于1,正准备去扣减库存,但是还没有来得及去扣减,此时线程2过来,线程2也去查询库存,发现这个数量一定也大于1,那么这两个线程都会去扣减库存,最终多个线程相当于一起去扣减库存,此时就会出现库存的超卖问题。

超卖原因流程图:

超卖原因

二、超卖解决方案

超卖问题是典型的多线程安全问题,针对这一问题的常见解决方案就是加锁:而对于加锁,我们通常有两种解决方案:

在这里插入图片描述
由于加入悲观锁,他认为安全问题一定发生,所以一定会获取锁进行串行执行,这样程序的性能跟吞吐量等受到很大的影响,效率大大降低,不到万不得已不使用悲观锁

使用乐观锁解决超卖问题

乐观锁:
会有一个版本号,每次操作数据会对版本号+1,再提交回数据时,会去校验是否比之前的版本大1 ,如果大1 ,则进行操作成功,这套机制的核心逻辑在于,如果在操作过程中,版本号只比原来大1 ,那么就意味着操作过程中没有人对他进行过修改,他的操作就是安全的,如果不大1,则数据被修改过,当然乐观锁还有一些变种的处理方式比如cas

程序中进行解决

我们进行扣减库存时,加入判断:

boolean success = seckillVoucherService.update().setSql("stock= stock -1") //set stock = stock -1.eq("voucher_id", voucherId).eq("stock",voucher.getStock()).update(); //where id = ? and stock = ?

以上逻辑的核心含义是:只要我扣减库存时的库存和之前我查询到的库存是一样的,就意味着没有人在中间修改过库存,那么此时就是安全的,但是以上这种方式通过测试发现会有很多失败的情况,失败的原因在于:在使用乐观锁过程中假设100个线程同时都拿到了100的库存,然后大家一起去进行扣减,但是100个人中只有1个人能扣减成功,其他的人在处理时,他们在扣减时,库存已经被修改过了,所以此时其他线程都会失败.

通俗一点将:
如果100个线程同时开始进行库存的扣减,只有一个线程在拿到100库存,这时他查询得到的是100,我扣减时候的库存是100,它可以完美运行,这时候库存变成99,剩下的99个线程开始扣减时,他们一开始拿到的是库存是100,扣减时发现库存变成了99,所以肯定就不会扣减,这样异常率就会特别高

修改上面的判断条件:
之前的方式要修改前后都保持一致,但是这样我们分析过,成功的概率太低,所以我们的乐观锁需要变一下,改成stock大于0 即可

boolean success = seckillVoucherService.update().setSql("stock= stock -1").eq("voucher_id", voucherId).update().gt("stock",0); //where id = ? and stock > 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/11101.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue使用qrcodejs2-fix或者qrcodejs2插件生成二维码

1. vue2安装 npm i qrcodejs2 1.1. vue3安装 npm install qrcodejs2-fix 2. 组件中引入并封装成公共组件&#xff0c;vue3版 <template><!-- 二维码生成 --><div class"body-div"><div style"width: 100%;height: 100%;" :id&quo…

入门Linux基本指令(2)

这篇文章主要提供一些对文件操作的Linux基本指令&#xff0c;希望对大家有所帮助&#xff0c;三连支持&#xff01; 目录 cp指令(复制) mv指令(剪切) nano指令 cat指令(打印文件内容) > 输出重定向 >> 追加重定向 < 输入重定向 more指令 less指令(推荐) …

Ueditor 百度强大富文本Springboot 项目集成使用(包含上传文件和上传图片的功能使用)简单易懂,举一反三

Ueditor 百度强大富文本Springboot 项目集成使用 首先如果大家的富文本中不考虑图片或者附件的情况下&#xff0c;只考虑纯文本且排版的情况下我们可以直接让前端的vue来继承UEditor就可以啦。但是要让前端将那几个上传图片和附件的哪些功能给阉割掉&#xff01; 然后就是说如…

Spring Batch教程(三)示例:从mysql中读取数据写入文本和从多个文本中读取内容写入mysql

Spring batch 系列文章 Spring Batch教程&#xff08;一&#xff09; 简单的介绍以及通过springbatch将xml文件转成txt文件 Spring Batch教程&#xff08;二&#xff09;示例&#xff1a;将txt文件转成xml文件以及读取xml文件内容存储到数据库mysql Spring Batch教程&#xff…

elasticsearch IK分词器

说明&#xff1a;es默认的分词器对中文的识别不是特别好&#xff0c;一段话的分词是一个一个汉字&#xff0c;这显然没有达到想要的结果。 可以安装IK分词器&#xff0c;兼容中文的分词&#xff1b; IK分词器 安装 安装IK分词器&#xff0c;例如elasticsearch的容器名为es&a…

MATLAB与ROS联合仿真——控制类功能模块介绍

1、Keyboard Control &#xff08;1&#xff09;输入参数&#xff1a;无 &#xff08;2&#xff09;输出参数&#xff1a;Speed Factor为输出的速度系数&#xff08;1代表前行&#xff0c;0停止&#xff0c;-1代表后退&#xff09;&#xff0c;Turn Factor为输出的舵机系数&am…

webpack联邦模块介绍及在dumi中使用问题整理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、ModuleFederationPlugin参数含义&#xff1f;二、如何在dumi中使用及问题整理1. 如何在dumi中使用(这个配置是好使的)2.相关问题整理2.1 问题12.2 问题2 总…

【LeetCode-中等】剑指 Offer 67. 把字符串转换成整数(详解)

题目 写一个函数 StrToInt&#xff0c;实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。 首先&#xff0c;该函数会根据需要丢弃无用的开头空格字符&#xff0c;直到寻找到第一个非空格的字符为止。 当我们寻找到的第一个非空字符为正或者负号时&#…

【浩鲸科技】济南Java后端面经

本文目录 写在前面试题总览题目解析1.说一下SpringBoot中常用的注解2.Redis中的基本数据类型3.TCP的网络协议4.java中常见的锁5.Hashmap的底层数据结构、底层源码、扩容机制源码6.java面向对象的特点 写在前面 关于这个专栏&#xff1a; 本专栏记录一些互联网大厂、小厂的面试实…

华为HCIP第二节-------------------------ISIS

IS-IS&#xff08;Intermediate System to Intermediate System&#xff0c;中间系统到中间系统&#xff09;是ISO &#xff08;International Organization for Standardization&#xff0c;国际标准化组织&#xff09;为它的CLNP&#xff08;ConnectionLessNetwork Protocol&…

Vue 常用指令 v-on 自定义参数和事件修饰符

自定义参数就是可以在触发事件的时候传入自定义的值。 文本框&#xff0c;绑定了一个按钮事件&#xff0c;对应的逻辑是sayhi&#xff0c;现在无论按下什么按钮都会触发这个sayhi。但是实际上不是所有的按钮都会触发&#xff0c;只会限定某一些按钮&#xff0c;最常见的按钮就…

【能量管理系统( EMS )】基于粒子群算法对光伏、蓄电池等分布式能源DG进行规模优化调度研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

MyBatis学习笔记之逆向工程

文章目录 逆向工程配置与生成QBC查询风格 所谓的逆向工程是&#xff1a;根据数据库表逆向生成的Java的pojo类、SqlMapper.xml文件、以及mapper接口类等 要完成这个工作&#xff0c;需要借助别人写好的逆向工程插件。 虽然有点经典白学&#xff0c;但好像也没不白学 思考&#x…

【爬虫案例】用Python爬取iPhone14的电商平台评论

用python爬取某电商网站的iPhone14评论数据&#xff0c; 爬取目标&#xff1a; 核心代码如下&#xff1a; 爬取到的5分好评&#xff1a; 爬取到的3分中评&#xff1a; 爬取到的1分差评&#xff1a; 所以说&#xff0c;用python开发爬虫真的很方面&#xff01; 您好&…

基于Java+Springboot+Vue的民宿管理系统(源代码+数据库)092

基于JavaSpringbootVue的民宿管理系统(源代码数据库)092 一、系统介绍 本项目前后端分离 本系统分为管理员、商家、用户三种角色 用户角色包含以下功能&#xff1a; 注册、登录、民宿信息查看、房间信息(查看/预订/评论/收藏/退订/投诉)、在线客服、房间预订管理、房间退订…

基于vue3.0实现vr全景编辑器

随着社会的不断发现&#xff0c;现实生活中有很多时候会使用到全景现实&#xff0c;比如房地产行业vr看房&#xff0c;汽车行业vr看车之类的&#xff0c;全景可视化真实还原了现场的场景&#xff0c;真正做到沉浸式体验。 现在我们基于vue3.0版本开发出了一款沉浸式的编辑器&a…

前后端项目分离开发

问题说明&#xff1a; 开发人员同时负责前端和后端代码开发&#xff0c;分工不明确开发效率低前后端代码混合在一个工程中&#xff0c;不便于管理对开发人员要求高&#xff0c;人员招聘困难 解决方法&#xff1a; 前后端分离开发 介绍 前后端分离开发&#xff0c;就是在项…

Asp.Net 6中使用Log4Net

Asp.Net 6中使用Log4Net 1. 先新建一个ASP.NET Core空项目 2. 通过Nuget包管理器安装下面两个包 log4net Microsoft.Extensions.Logging.Log4Net.AspNetCore 3. 在项目根目录下新建log4net的配置文件log4net.config&#xff0c;并将其设置为始终复制。 <?xml version&quo…

【Spring】IOC的原理

一、 IOC 的概念 Spring 的 IOC &#xff0c;即控制反转&#xff0c;所谓控制反转 —— 本来管理业务对象&#xff08;bean&#xff09;的操作是由我们程序员去做的&#xff0c;但是有了 Spring 核心容器后&#xff0c;这些 Bean 对象的创建和管理交给我们Spring容器去做了&am…

如何选择低代码/零代码平台(最全平台总结)

来谈论这个问题之前&#xff0c;我们先来看看到底什么是低代码/零代码—— 低代码 对于“低代码”的宣传其实已经很久很广泛了&#xff0c;但是争议从来都没有停止。 忘记之前在哪里看到过一个“低代码将会取代程序员”之类的说法&#xff0c;觉得很好笑&#xff0c;看了一些…