Lua脚本操作redis

模拟库存扣减

基础版

@SpringBootTest
class LuaTests {@Resource(name="redisTemplate")ValueOperations<String,Long> valueOperations;@AutowiredStringRedisTemplate stringRedisTemplate;final  String priductKey = "product.1";@Testvoid test1() throws IOException {StringBuilder sb = new StringBuilder();sb.append(" local key = KEYS[1] ");sb.append(" local qty = ARGV[1] ");sb.append(" local redis_qty = redis.call('get',key) ");sb.append(" if tonumber(redis_qty) >= tonumber(qty)  then ");sb.append("   redis.call('decrby',key,qty) ");sb.append("  return  -1 "); // -1 代表的扣减成功了sb.append(" else ");sb.append("  return tonumber(redis_qty)  "); //返回的当前的库存量 , 0,1,2 .......sb.append(" end ");RedisScript<Long>  script =  RedisScript.of(sb.toString(),Long.class);ExecutorService executorService = Executors.newCachedThreadPool();for (int i = 0; i < 10; i++) {executorService.execute(()->{int needQty = RandomUtil.randomInt(1,5);Long qty = stringRedisTemplate.execute(script, CollUtil.newArrayList(priductKey), needQty + "");if(qty == -1 ){System.out.println(StrUtil.format("{} 扣减成功,需求量是:{}",Thread.currentThread().getId(),needQty));} else {System.out.println(StrUtil.format("{} 扣减失败,您的需求量是:{},当前库存量是:{}",Thread.currentThread().getId(),needQty,qty));}});}System.in.read();}

升级版

@Testvoid test2() throws IOException {final String key1 = "product.1";final String key2 = "product.2";final String key3 = "product.3";valueOperations.set(key1,5l);valueOperations.set(key2,10l);valueOperations.set(key3,15l);StringBuilder sb = new StringBuilder();sb.append(" local table = {} ");sb.append(" local redis_qtys =  redis.call('mget',unpack(KEYS)) ");sb.append(" for i=1, #KEYS do ");sb.append("  if  tonumber(ARGV[i]) >  tonumber(redis_qtys[i]) then");sb.append("   table[#table + 1] = KEYS[i] .. '=' .. redis_qtys[i]  "); // product.2=56sb.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>  script =  RedisScript.of(sb.toString(),List.class);ExecutorService executorService = Executors.newCachedThreadPool();for (int i = 0; i < 1; i++) {executorService.execute(()->{int needQty1 = RandomUtil.randomInt(1,7);int needQty2 = RandomUtil.randomInt(1,10);int needQty3 = RandomUtil.randomInt(1,16);List ret = stringRedisTemplate.execute(script, CollUtil.newArrayList(key1,key2,key3), needQty1+"",needQty2+"",needQty3+"");if(ret.size() == 0 ){System.out.println(StrUtil.format("{} 扣减成功,需求量是:{},{},{}",Thread.currentThread().getId(),needQty1,needQty2,needQty3));} else {System.out.println(StrUtil.format("{} 扣减失败,您的需求量是:{},{},{} ",Thread.currentThread().getId(),needQty1,needQty2,needQty3));for(Object obj :ret){System.out.println(obj);}}});}System.in.read();}

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

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

相关文章

Java NIO, IO 整理

NIO: IO多路复用: 参考: Redis&#xff08;六&#xff09;单线程I/O多路复用模型浅析_单线程多路复用-CSDN博客 Java NIO 详解_java nio详解_开发菜鸡的博客-CSDN博客 Java Socket 之 NIO - 掘金 答应我&#xff0c;这次搞懂 I/O 多路复用&#xff01;_小林coding的博客-CS…

Spring JdbcTemplate

一、简介 Spring 框架对 JDBC 进行封装&#xff0c;使用 JdbcTemplate 方便实现对数据库操作。它是 spring 框架中提供的一个对象&#xff0c;是对原始 Jdbc API 对象的简单封装。spring 框架为我们提供了很多的操作模板类。 针对操作关系型数据&#xff1a; jdbcTemplateHibe…

A* 算法简介

一、A* 算法简介A* algorithm is a popular choice for graph search. Breadth First Search is the simplest of the graph search algorithms. Graph search algorithms, including A*, take a “graph” as input. A* algorithm is a modification of Dijkstra’s Algorithm…

华为OD机试 - 部门人力分配(Java JS Python C)

题目描述 部门在进行需求开发时需要进行人力安排。 当前部门需要完成 N 个需求,需求用 requirements 表述,requirements[i] 表示第 i 个需求的工作量大小,单位:人月。 这部分需求需要在 M 个月内完成开发,进行人力安排后每个月人力时固定的。 目前要求每个月最多有2个…

在k8s中部署nfs-client-provisioner

1、部署过程 1.1、环境依赖 在部署nfs-client-provisioner之前&#xff0c;需要先部署nfs服务。 因为&#xff0c;nfs-client-provisioner创建的pv都是要在nfs服务器中搭建的。 本示例中的nfs server的地址如下&#xff1a; [rootnode1 /]# showmount -e Export list for …

pinia 持久化插件使用

官方文档 本文主要介绍 vue3组合式 api 使用持久化插件的写法。 选项式 写法官方已给出 安装依赖 pnpm i pinia-plugin-persistedstate插件的使用 import { createPinia } from pinia import piniaPluginPersistedstate from pinia-plugin-persistedstateconst pinia creat…

JavaMap工具类(MapUtils)

1、Object转Map 2、将 map 中的 value 为null的的元素转成空字符串"" 3、map转Object 4、MAP 判空 5、Map 排序 按key值长度进行排序 6、两个MAP对比&#xff0c;在oldMap中移除remMap中所有的key值 备注&#xff1a;排序的话(TreeMap)是可以直接实现简单排序的…

VR转接线方案/VR Link串流数据线方案/VR眼镜PD快充方案

虚拟现实技术(英文名称&#xff1a;Virtual Reality&#xff0c;缩写为VR)&#xff0c;又称虚拟实境或灵境技术&#xff0c;是20世纪发展起来的一项全新的实用技术。虚拟现实技术囊括计算机、电子信息、仿真技术&#xff0c;其基本实现方式是以计算机技术为主&#xff0c;利用并…

Java:commons-lang3中的StringUtils.strip实现移除字符串首尾字符

依赖 <dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version> </dependency>示例 // 包名 import org.apache.commons.lang3.StringUtils;// 处理字符串&…

kafka支持外网访问

kafka支持外网访问 1.kafka正常部署之后如果不修改&#xff0c;外网是无法访问的&#xff0c;具体如下&#xff08;这里是单节点&#xff09; 2.这个时候需要修改kafka的config中的server.properties中的 listeners 修改为0.0.0.0 监控所有网卡&#xff0c;advertised.listene…

管理空闲存储空间

位示图是操作系统中一种管理空闲存储空间的方法。管理空闲除使用位示图法还可用&#xff1a;空闲区表法&#xff0c;空闲链表法&#xff0c;成组链接法 1.空闲区表法 空闲表法属于连续分配方法。它与内存管理中的动态分区分配方法雷同。 将外存空间上一个连续未分配区域称为“…

[三次反转法]循环移动数组元素

循环移动 题目描述 给定一组整数&#xff0c;要求利用数组把这组数保存起来&#xff0c;然后实现对数组的循环移动。假定供有n个整数&#xff0c;则要使前面各数顺序向后移m个位置&#xff0c;并使最后m个数变为最前面的m个数(m<n)。 注意&#xff0c;不要用先输出后m个数…

口袋参谋:如何对订单实现一键批量插旗?

​在淘宝店铺运营中&#xff0c;对宝贝订单标注插旗&#xff0c;也算是常态了&#xff0c;至少90%的商家都不陌生&#xff0c;剩下的10%是刚入行的新手&#xff0c;正如我刚入行一样。 01 首先我们要了解什么是插旗&#xff1f; 其实就是淘宝店铺利用各种颜色的旗子来代表订单…

A-23 P离子交换树脂:高效去除无机有机污染物的新选择

在当今水处理行业中&#xff0c;高效、环保的离子交换树脂备受关注。本文将为您介绍一款具有卓越性能的碱性季胺基阴离子交换树脂——Tulsion A-23 P。通过分析其特性和应用&#xff0c;展示其在水处理领域的优势。 一、Tulsion A-23 P离子交换树脂的特性 物理化学稳定性&#…

Vue生命周期函数执行顺序(使用注意事项)

文章目录 beforeCreatecreatedbeforeMountmountedbeforeUpdateupdatedbeforeDestroydestroyed Vue.js 是一个基于 MVVM 模式的前端框架&#xff0c;它的核心是一个响应式的数据绑定系统。在 Vue.js 中&#xff0c;组件是一个可复用的 Vue 实例&#xff0c;它拥有自己的生命周期…

input聚焦,失去焦点的那些事

需求&#xff1a; 1&#xff1a;搜索输入时显示清空按钮和搜索按钮&#xff1b; 2&#xff1a;点击搜索按钮失去焦点&#xff0c;并查询&#xff1b; 3&#xff1a;点击清空按钮后重新聚焦&#xff1b; 需要解决的问题&#xff1a; 1&#xff1a;失去焦点需要别的处理的话要加…

Linux命令——nc

Linux命令——nc 文章目录 Linux命令——nc例子客户端/服务端模型数据传输与服务端交互端口扫描使用代理发送文件聊天工具一次性 Web Server文件夹传输远程克隆磁盘shell反向 shell 参考 netcat&#xff0c;简写为 nc&#xff0c;是 unix 系统下一个强大的命令行网络通信工具&a…

JS手写Promise.all方法

测试例子 var f11 Promise.resolve("111");var f22 Promise.resolve("222");var f33 Promise.resolve("333");// var f33 Promise.reject("333");1、用原生 Promise 实现 逻辑说明&#xff1a;接收一个由多个promise方法组成的数组…

uniapp开发小程序-pc端小程序下载后端接口的二进制流文件

fileName包含文件名后缀名&#xff0c;比如test.png这种格式 api.DownloadTmtFile后端接口返回的是文件的二进制流 值得注意的是&#xff0c;微信开发者工具中是测试不了wx.saveFileToDisk的&#xff0c;需要真机或者体验版测试 handleDownload(fileName) {if (!fileName) retu…

mysql表的字段建议加上NOT NULL约束

mysql的列加上NOT NULL约束&#xff0c;这是一个好的实践&#xff08;但不是一个强制要求&#xff09;&#xff0c;因为它能带来一些好处&#xff0c;例如&#xff1a; 设置为NOT NULL&#xff0c;可以确保该列没有NULL值&#xff0c;对该列的数据的规范性进行约束。加上NOT N…