当前位置: 首页 > news >正文

Lua脚本的使用

一、使用lua脚本扣减单个商品的库存

@SpringBootTest
class LuaTests {@AutowiredStringRedisTemplate stringRedisTemplate;@Testvoid test3() {for (int i = 1; i <= 5; i++) {stringRedisTemplate.opsForValue().set("product."+i,String.valueOf(i));}}@Testvoid test2() {StringBuilder sb = new StringBuilder();sb.append(" local key = KEYS[1] "); // 你要扣减的key :product.1sb.append(" local qty = ARGV[1] "); // 你要扣减的数量,需求量sb.append(" local redis_qty = redis.call('get',key) "); //获取redis库存实际数量sb.append(" if tonumber(redis_qty) >= tonumber(qty) then ");//需求量与库存量对比sb.append("     redis.call('decrby',key,qty) "); //满足sb.append("   return -1  "); //满足sb.append(" else ");sb.append("   return tonumber(redis_qty) ");  //不满足,就给剩余库存量 ,0 1 2 。。。。sb.append(" end ");RedisScript<Long> luaScript = RedisScript.of(sb.toString(), Long.class);ExecutorService executorService = Executors.newFixedThreadPool(5);for (int i = 1; i <= 5; i++) {executorService.execute(()->{int qty = RandomUtil.randomInt(1,6);Long count = stringRedisTemplate.execute(luaScript, CollUtil.newArrayList("product.5"),String.valueOf(qty));if (count == -1L) {System.out.println(Thread.currentThread().getId() + " 扣减成功,扣减了-> "+ qty);} else {System.out.println(Thread.currentThread().getId() + "扣减失败,需求量是:"+qty+",剩余库存量:"+count);}});}// 线程睡眠3秒 ThreadUtil.safeSleep(3000);}
}

二、使用lua脚本扣减多个商品的库存

@Testvoid test4() {StringBuilder sb = new StringBuilder();sb.append(" local table = {}  "); // 你要扣减的key :product.1sb.append(" local values =  redis.call('mget',  unpack(KEYS) )"); // [product.1,product.2]   =>  product.1 product.2sb.append(" for i = 1, #KEYS   do  ");sb.append("   if  tonumber(ARGV[i]) > tonumber(values[i])   then ");// ..的意思就是组合,也就是字符串相加sb.append("     table[#table + 1] =  KEYS[i] .. '=' .. values[i] "); //product.1=23sb.append("   end ");sb.append(" end ");sb.append(" if #table > 0 then ");sb.append("   return table  ");sb.append(" end ");sb.append(" for i = 1 , #KEYS do ");sb.append("   redis.call('decrby',KEYS[i],ARGV[i])  ");sb.append(" end ");sb.append(" return {} ");RedisScript<List> luaScript = RedisScript.of(sb.toString(), List.class);List<StockProduct> stockProducts =  new ArrayList<>();stockProducts.add(new StockProduct(5,1));stockProducts.add(new StockProduct(4,2));List<String> keys = stockProducts.stream().map(it -> "product." + it.getId()).collect(Collectors.toList());Object[] qtys = stockProducts.stream().map(it -> it.getQty() + "").toArray();List<String> list = stringRedisTemplate.execute(luaScript,keys,qtys);if(list.isEmpty()){System.out.println("库存冻结成功");} else {for (String key_qty : list) {String[] split = key_qty.split("=");System.out.println(split[0] + "库存不足,剩余库存量:" + split[1]);}}ThreadUtil.safeSleep(3000);}

三、通过分布式锁,扣减商品的库存

package com.by;import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import com.by.moder.Student;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;import javax.annotation.Resource;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;@SpringBootTest
class SetNXTests {@AutowiredStringRedisTemplate stringRedisTemplate;// @Autowired@Resource(name = "redisTemplate")ValueOperations<String,String> valueOperations;@Testvoid Test() {//线程池ExecutorService executorService = Executors.newFixedThreadPool(5);for (int i = 1; i <=5; i++) {executorService.execute(()->{//某一个工人String ioId = "IO"+ RandomUtil.randomInt(1,1000);while (true){// 判断是否存在Boolean b = valueOperations.setIfAbsent("lock.product.1",ioId+":"+ DateUtil.now());if(b){System.out.println(Thread.currentThread().getId()+"获取到了分布式锁");//执行业务ThreadUtil.safeSleep(3000);// 执行业务成功后stringRedisTemplate.delete("lock.product.1");System.out.println(Thread.currentThread().getId()+"释放了分布式锁");break;}else {//Thread.currentThread().getId() :当前线程的idSystem.out.println(Thread.currentThread().getId()+"没有获取到分布式锁");ThreadUtil.safeSleep(1000);}}});}//睡眠ThreadUtil.safeSleep(100000);}
}

相关文章:

Lua脚本的使用

一、使用lua脚本扣减单个商品的库存 SpringBootTest class LuaTests {AutowiredStringRedisTemplate stringRedisTemplate;Testvoid test3() {for (int i 1; i < 5; i) {stringRedisTemplate.opsForValue().set("product."i,String.valueOf(i));}}Testvoid test…...

hcia datacom课程学习(5):MAC地址与arp协议

1.MAC地址 1.1 含义与作用 &#xff08;1&#xff09;含义&#xff1a; mac地址也称物理地址&#xff0c;是网卡设备在数据链路层的地址&#xff0c;全世界每一块网卡的mac地址都是唯一的&#xff0c;出厂时烧录在网卡上不可更改 &#xff08;2&#xff09;作用&#xff1a…...

unbuntu mysql8.0新建用户及开启远程连接

MySQL更新到8.0以上版本后&#xff0c;在创建连接远程的用户的时候和之前5.x的版本有了很大的不同&#xff0c;不能使用原来同时创建用户和授权的命令。 以下是记录的MySQL8.0创建用户并授权的命令&#xff1a; 查看用户表&#xff1a; user mysql; select host,user,authen…...

Intel FPGA (1):线性序列机

Intel FPGA (1)&#xff1a;线性序列机 前提摘要 个人说明&#xff1a; 限于时间紧迫以及作者水平有限&#xff0c;本文错误、疏漏之处恐不在少数&#xff0c;恳请读者批评指正。意见请留言或者发送邮件至&#xff1a;“Email:noahpanzzzgmail.com”。本博客的工程文件均存放在…...

翻译: 硅谷软件工程师面试:准备所需的一切

没有人有时间去做成百上千道LeetCode题目&#xff0c;好消息是你实际上并不需要做那么多题目就能够在FAANG公司找到工作&#xff01; 我曾经在Grab工作&#xff0c;这是东南亚的一家共享出行公司&#xff0c;但我对工作感到沮丧&#xff0c;想要进入FAANG公司&#xff0c;但我…...

视频推拉流EasyDSS点播平台云端录像播放异常的问题排查与解决

视频推拉流EasyDSS视频直播点播平台可提供一站式的视频转码、点播、直播、视频推拉流、播放H.265视频等服务&#xff0c;搭配RTMP高清摄像头使用&#xff0c;可将无人机设备的实时流推送到平台上&#xff0c;实现无人机视频推流直播、巡检等应用。 有用户反馈&#xff0c;项目现…...

kubuntu23.10安装sdl2及附加库和 sfml2.5.1

2024年3月28号&#xff0c;四&#xff0c;晚上kubuntu23.10下安装了sdl2的如下&#xff0c;没有安装gfx。 sudo apt install libsdl2-dev sudo apt install libsdl2-image-dev sudo apt install libsdl2-ttf-dev sudo apt install libsdl2-mixer-dev sudo apt install libsdl2…...

Centos JDK1.8 下载安装

https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html 一 RPM包安装 rpm -ivh jdk-8u391-linux-x64.rpm /etc/profile export JAVA_HOME/usr/java/jdk1.8.0-x64 export PATH$JAVA_HOME/bin:$PATHsource /etc/profile二 tar.gz 包手动…...

iOS开发进阶(十四):xcodebuild 命令应用详解

文章目录 一、前言二、xcodebuild 命令汇总三、xcodebuild 可选命令四、exportOptionsPlist文件内容配置说明五、项目实操六、拓展阅读 一、前言 关于iOS组包&#xff0c;详参博文《ReactNative进阶&#xff08;三十四&#xff09;&#xff1a;Jenkins 流水线 组包 iOS 应用包…...

uniapp 开发之原生Android插件

开发须知 在您阅读此文档时&#xff0c;我们假定您已经具备了相应Android应用开发经验&#xff0c;使用Android Studio开发过Android原生。也应该对HTML,JavaScript,CSS等有一定的了解, 并且熟悉在JavaScript和JAVA环境下的JSON格式数据操作等。 为了插件开发者更方便快捷的开…...

构建第一个JS应用(FA模型)

创建JS工程 若首次打开DevEco Studio&#xff0c;请点击Create Project创建工程。如果已经打开了一个工程&#xff0c;请在菜单栏选择File > New > Create Project来创建一个新工程。选择Application应用开发&#xff08;本文以应用开发为例&#xff0c;Atomic Service对…...

物联网学习2、MQTT 发布/订阅模式介绍

MQTT 发布/订阅模式 发布订阅模式&#xff08;Publish-Subscribe Pattern&#xff09;是一种消息传递模式&#xff0c;它将发送消息的客户端&#xff08;发布者&#xff09;与接收消息的客户端&#xff08;订阅者&#xff09;解耦&#xff0c;使得两者不需要建立直接的联系也不…...

docker--部署 (超详版) (五)

环境准备&#xff1a;docker&#xff0c;mysql&#xff0c;redis&#xff0c;镜像&#xff0c;nginx 把虚拟机打开&#xff0c;连接xshell&#xff0c;参考博客&#xff1a; https://blog.csdn.net/m0_74229802/article/details/136965820?spm1001.2014.3001.5501 一&#x…...

谷粒商城——通过接口幂等性防止重复提交订单

如果用户向后端服务提交多次相同订单的提交服务&#xff0c;那么后端应该只生成一条订单记录。 有一些操作天然是幂等的&#xff0c;如查询操作和删除操作等。 幂等性实现 1.token机制&#xff08;仅这个方法适用于订单的重复提交&#xff09; 后端先生成1个令牌将其记录在R…...

谈谈MVCC机制

在MySQL中&#xff0c;MVCC&#xff08;多版本并发控制&#xff09;是InnoDB存储引擎使用的并发控制机制。它提供对数据的并发访问&#xff0c;并确保多用户环境中数据的一致性和隔离性。 InnoDB通过“Undo log”存储每条记录的多个版本&#xff0c;提供历史记录供读取&#x…...

Linux之用户账号、用户组和与账号有关的系统文件

目录 一、基本介绍 1.用户和用户组 2.UID和GID 二、 账户管理 1.查看用户的UID和GID 2.添加账户 3.删除账号 4.修改账号 5.账户口令 三、分组管理 1.新增用户组 2.删除用户组 3.修改用户组 4.用户组切换 四、与账号有关的系统文件 1./etc/passwd 2./etc/shado…...

mac 安装 pip,如果你的电脑已经有 python3

文章目录 如果没装 如果你的电脑已经有 python3. 安装 pip 执行以下命令&#xff0c; 输入 python3 -m ensurepip --upgrade &#xff0c;按下Enter就大功告成了&#xff01; 安装后查看版本&#xff1a; pip3 -V 如果没装 先安装 python&#xff0c;建议使用 homebrew。 …...

java 枚举

枚举的格式 枚举是一种特殊的类 枚举类的最开始必须罗列所有类型 枚举类提供了一些父类的方法 values() :获取所有的的枚举对象,是一个数组 public enum A {A1, A2, A3;String name;A() {this.name "default";}String getName() {return name;}void setName(Strin…...

Java学习之类和对象、内存底层

目录 表格结构和类结构 表格的动作和类的方法 与面向过程的区别 具体实现 对象和类的详解 类的定义 属性&#xff08;field 成员变量&#xff09; 方法 示例--编写简单的学生类 简单内存分析(理解面向对象) 构造方法(构造器 constructor) 声明格式&#xff1a; 四…...

递归遍历目录结构和树状展现

在D盘下创建文件夹“电影”&#xff0c;在文件夹“电影”下创建“华语”、“好莱坞”&#xff0c;在文件夹“华语”下创建文件“人民的名义.mp4”、“天安门传奇.mp4”、“程序员统治世界.mp4”&#xff0c;在文件夹“好莱坞”下创建文件“国王的演讲.mp4”、“速度与激情8.mp4…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...