使用redis+lua通过原子减解决超卖问题【示例】
系列文章目录
一、SpringBoot连接MySQL数据库实例【tk.mybatis连接mysql数据库】
二、SpringBoot连接Redis与Redisson【代码】
三、SpringBoot整合WebSocket【代码】
四、使用redis+lua通过原子减解决超卖问题【示例】
五、SpringBoot整合Elasticsearch【代码示例】
文章目录
- 系列文章目录
- 前言
- 一、准备工作
- 二、不使用Lua
- 三、使用Lua
前言
超卖,即在并发的情况下,所售商品数量大于商品的库存数量。在并发量大的情况下,用户请求同时到达,对数据库进行操作,在没有采取相应的处理的情况时从而导致出现超卖现象。
一、准备工作
在redis中放入十件商品
二、不使用Lua
使用20个线程抢商品
public void test () {ExecutorService service = Executors.newFixedThreadPool(20);for (int i = 0; i < 20; i++) {int finalI = i;service.execute(new Runnable() {@Overridepublic void run() {if (Integer.parseInt(String.valueOf(redisUtils.get("test"))) > 0) {int execute = Integer.parseInt(String.valueOf(redisUtils.decr("test", 1)));if (execute != 0) {log.info("线程" + finalI + "抢到了商品!!!");} else {log.info("线程" + finalI + "未抢到商品");}} else {log.info("商品数量不足");}}});}
}
运行代码发现已经超出了十个人抢到了商品。
此时redis的存值已经变为了负数,出现了超卖的情况。
三、使用Lua
public void test_lua () {StringBuilder sb = new StringBuilder();sb.append("if (redis.call('exists', KEYS[1]) == 1) then"); // 判断key是否存在sb.append(" local stock = tonumber(redis.call('get', KEYS[1]));"); // 获取锁sb.append(" if (stock == -1) then");sb.append(" return 1;");sb.append(" end;");sb.append(" if (stock > 0) then");sb.append(" redis.call('decrby', KEYS[1], 1);"); // 商品数量减1sb.append(" return stock;");sb.append(" end;");sb.append(" return 0;");sb.append("end;");sb.append("return -1;");String STOCK_LUA = sb.toString();DefaultRedisScript<Long> objectDefaultRedisScript = new DefaultRedisScript<>();objectDefaultRedisScript.setScriptText(STOCK_LUA);objectDefaultRedisScript.setResultType(Long.class);ArrayList<String> keys = new ArrayList<>(); // 脚本中的KEYS参数keys.add("test");ExecutorService service = Executors.newFixedThreadPool(20);for (int i = 0; i < 20; i++) {int finalI = i;service.execute(new Runnable() {@Overridepublic void run() {int execute = Integer.parseInt(redisTemplate.execute(objectDefaultRedisScript, keys).toString());if (execute != 0) {log.info("线程" + finalI + "抢到了商品!!!");} else {log.info("线程" + finalI + "未抢到商品");}}});}
}
依然使用20个线程抢商品,运行代码只有10个线程抢到了商品
此时redis中的存值为0
相关文章:

使用redis+lua通过原子减解决超卖问题【示例】
系列文章目录 一、SpringBoot连接MySQL数据库实例【tk.mybatis连接mysql数据库】 二、SpringBoot连接Redis与Redisson【代码】 三、SpringBoot整合WebSocket【代码】 四、使用redislua通过原子减解决超卖问题【示例】 五、SpringBoot整合Elasticsearch【代码示例】 文章目录 系…...

WebFlux异常处理:onErrorReturn和onErrorResume
1 缘起 最近在学习WebFlux, 处理异常时遇到些问题,比如,Java直接抛出的异常无法直接被onErrorReturn和onErrorResume捕获, 但是,在map或者flatMap等方法之后的异常又可以直接被捕获, 于是,进行…...

《动手学深度学习 Pytorch版》 4.5 权重衰减
4.5.1 范数与权重衰减 整节理论,详见书本。 4.5.2 高维线性回归 %matplotlib inline import torch from torch import nn from d2l import torch as d2l# 生成一些数据,为了使过拟合效果更明显,将维数增加到 200 并使用一个只包含 20 个样…...

数据脱敏的风险量化评估介绍
1、背景介绍 当前社会信息化高速发展,网络信息共享加速互通,数据呈现出规模大、流传快、类型多以及价值密度低的特点。人们可以很容易地对各类数据实现采集、发布、存储与分析,然而一旦带有敏感信息的数据被攻击者获取将会造成个人隐私的严重…...
SpringCloudGateway网关实战(三)
SpringCloudGateway网关实战(三) 上一章节我们讲了gateway的内置过滤器Filter,本章节我们来讲讲全局过滤器。 自带全局过滤器 在实现自定义全局过滤器前, spring-cloud-starter-gateway依赖本身就自带一些全局过滤器࿰…...
08在MyBatis-Plus中配置多数据源
配置多数据源 模拟多库场景 适用于多种场景: 多库(操作的表分布在不同数据库当中),读写分离(有的数据库负责查询的功能,有的数据库负责增删该的功能),一主多从,混合模式等 第一步: 模拟多库,在mybatis_plus数据库中创建user表,在mybatis_plus_1数据库中创建product表 --创建…...

Centos8安装docker并配置Kali Linux图形化界面
鉴于目前网上没有完整的好用的docker安装kali桌面连接的教程,所以我想做一个。 准备工作 麻了,这服务器供应商提供的镜像是真的纯净,纯净到啥都没有。 问题一:Centos8源有问题 Error: Failed to download metadata for repo ap…...

游戏开发初等数学基础
凑数图() 立体图形面积体积 1. 立方体(Cube): 表面积公式: 6 a 2 6a^2 6a2 (其中 a a a 是边长)。体积公式: a 3 a^3 a3 (其中 a a a 是边长)。 2. 球体(Sphere): 表面积公…...
svg图片代码data:image/svg+xml转png图片方法
把代码保存为html格式的文件中,用浏览器访问,即可右键保存 从AI软件或其它网站得到svg图片代码后,把他复制到下面源码上 注意:src""图片地址中,一些参数的含义 d‘这里是图片代码数据’ viewBox是图片显示区域,宽,高等 fill%23000000’这里表示颜色 ,后面6位0表示黑色…...
解决问题:Replace `‘vue‘;⏎` with `“vue“;`
使用vscode写vue文件的问题: Replace vue;⏎ with "vue"; error Replace v-model:value"xxx"placeholder"inputsearch prettier/prettier 7:38 error Insert ⏎ potentially fixable with the --fix option 原因:格式问题&a…...

ThinkPHP 5.0通过composer升级到5.1,超级简单
事情是这样的,我实现一个验证码登录的功能,但是这个验证码的包提示tp5的版本可以是5.1.1、5.1.2、5.1.3。但我使用的是5.0,既然这样,那就升个级呗,百度了一下,结果发现大部分都是讲先备份application和修改…...

计算机竞赛 多目标跟踪算法 实时检测 - opencv 深度学习 机器视觉
文章目录 0 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习多目标跟踪 …...

一文了解大模型工作原理——以ChatGPT为例
文章目录 写在前面1.Tansformer架构模型2.ChatGPT原理3.提示学习与大模型能力的涌现3.1 提示学习3.2 上下文学习3.3 思维链 4.行业参考建议4.1 拥抱变化4.2 定位清晰4.3 合规可控4.4 经验沉淀 写在前面 2022年11月30日,ChatGPT模型问世后,立刻在全球范围…...
CPP-Templates-2nd--第十九章 萃取的实现 19.7---
目录 19.7 其它的萃取技术 19.7.1 If-Then-Else 19.7.2 探测不抛出异常的操作 19.7.3 萃取的便捷性(Traits Convenience) 别名模板和萃取(Alias Templates And Traits) 变量模板和萃取(Variable Templates and Traits&…...

python 采用selenium+cookies 获取登录后的网页
百度网页由于需要登陆手机短信验证。比较麻烦 这里我采用先人工登录百度账号,然后将百度账号的相关cookies保存下来 然后采用selenium动态登录网页 整体代码如下 from selenium import webdriverimport timeoptions webdriver.ChromeOptions()options.add_argu…...

【测试开发】答疑篇 · 什么是软件测试
【测试开发】答疑篇 文章目录 【测试开发】答疑篇1. 生活中的测试2. 什么是软件测试3. 为什么要有测试/没有测试行不行4. 软件测试和软件开发的区别5. 软件测试和软件调试之间的区别6. 软件测试的岗位7. 优秀测试人员具备的素质 【测试开发】答疑篇 软件不一定是桌面应用&#…...

深入解析顺序表:揭开数据结构的奥秘,掌握顺序表的精髓
💓 博客主页:江池俊的博客⏩ 收录专栏:数据结构探索👉专栏推荐:✅C语言初阶之路 ✅C语言进阶之路💻代码仓库:江池俊的代码仓库🔥编译环境:Visual Studio 2022Ἰ…...

数据风险量化评估方案
一、企业面临数据安全的痛点 1、企业缺少清晰的数据安全意识 各部门重视度不够,缺少主动数据安全管控意识。数据安全管控架构不清晰,职责划分不明确。对数据安全管控认识不全面、不深刻。工作人员对于所持有的数据缺乏概念,导致数据的价值无…...

EasyAVFilter代码示例之将视频点播文件转码成HLS(m3u8+ts)视频点播格式
以下是一套完整的视频点播功能开发源码,就简简单单几行代码,就可以完成原来ffmpeg很复杂的视频点播转码调用流程,而且还可以集成在自己的应用程序中调用,例如java、php、cgo、c、nodejs,不需要再单独一个ffmpeg的进程来…...
day-50 代码随想录算法训练营(19)动态规划 part 11
123.买卖股票的最佳时机||| 分析:只能买卖两次,就是说有五个状态: 没有买过第一次买入第一次卖出第二次买入第二次卖出 思路:二维数组,记录五个状态 1.dp存储:dp[i][1] 第一次买入 dp[i][2] 第一次卖…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...

免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...