springboot lua检查redis库存

devtools/2024/9/23 0:10:03/

需求

最近需求需要实现检查多个马戏场次下的座位等席对应库存渠道的库存余量,考虑到性能,决定采用Lua脚本实现库存检查。

数据结构

  • 库存层级结构
    在这里插入图片描述
  • redis库存hash类型结构
    在这里插入图片描述

实现

lua">--- 字符串分割为数组
local function split(str, char)local arr = {};local pattern = string.format('([^%s]+)', char);for item in string.gmatch(str, pattern) dotable.insert(arr, item);endreturn arr;
end
--- 数组转成map
local function toMap(tb)if (tb == nil) thenreturn {};endlocal map = {};for i = 1, #tb doif (i % 2 == 1) thenmap[tb[i]] = tb[i+1];endendreturn map;
end
--- 初始化数据,入参01:1,02:2.01:3
local argArr = {};
for rowItem in string.gmatch(ARGV[1], '([^.]+)') dolocal row = {};for keyVal in string.gmatch(rowItem, '([^,]+)') do-- 解析出每个key与valuelocal tempArr = split(keyVal, ':');row[tempArr[1]] = tempArr[2];endtable.insert(argArr, row);
end
--- 检查库存
for i = 1, #KEYS do--local rData = redis.call("HMGET", KEYS[i], '01 02');local rdsMap = toMap(redis.call("HGETALL", KEYS[i]));for tier, quantity in pairs(argArr[i]) do--redis.log(redis.LOG_NOTICE, string.format('key is:%s,tier is:%s,quantity is:%s', KEYS[i], tier, quantity));if (rdsMap[tier] == nil or tonumber(quantity) > tonumber(rdsMap[tier])) thenreturn string.format("库存key:%s,tier:%s不足", KEYS[i], tier);endend
end
return '';

遍历键值对时需要使用pairs而不是ipairs,二者区别如下:
for k,v in pairs(argArr)的遍历顺序并非是table类型数据的排列顺序,而是根据table中key的hash值排列的顺序来遍历的。
for k,v in ipairs(argArr)必须要求table中的key为有序的,而且必须是从1开始,ipairs只会从1开始按连续的key顺序遍历到key不连续为止。

  • 入参设计
    由于RedisTemplate直接传入集合为参数序列化后会有中括号,而lua脚本table类型使用花括号定义,因此采用字符串作为入参,在lua脚本中解析字符串为table类型。例如参数01:1,02:2.01:3代表二维数组,第一行为01:1,02:2,其中01为渠道,1为渠道对应的库存,英文逗号作为渠道分隔符。
  • springboot调用lua脚本
@Autowired
private StringRedisTemplate redisJsonTemplate;@Test
public void checkInventory() {List<String> keyList = List.of("stock:GZ7:433680411156197407", "stock:GZ7:433680411156197408");// 执行 lua 脚本DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();// 指定 lua 脚本redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("/lua/TheaterStockCheck.lua")));// 指定返回类型redisScript.setResultType(String.class);Object result = redisJsonTemplate.execute(redisScript, keyList, "01:1,0101:2.01:3");//01:1,02:2.01:3System.out.println(result);
}

调用lua脚本需要使用string序列化方式,使用jdk序列化方式会导致序列化后的数据lua脚本无法解析

  • 测试效果
    • redis库存数据
      在这里插入图片描述
    • 调用效果
      在这里插入图片描述

http://www.ppmy.cn/devtools/39152.html

相关文章

element ui的table多选

使用el-table的selection-change事件来获取选中的值&#xff1b; 例&#xff1a; html代码&#xff1a; <el-button type"primary" click"openTableSet">列表设置</el-button><!-- 列表设置弹框 --> <el-dialog :close-on-click-mo…

Mybatis-Plus常用的增删改查坑

添加依赖 <!--实体类上加上Data注解就不用写get&#xff0c;set&#xff0c;toString&#xff0c;equals等方法了--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional…

Linux内核--设备驱动(六)媒体驱动框架整理(2)--视频

目录 一、引言 二、V4L2 ------>2.1、主要结构体 ------------>2.2.1、video_device ------------>2.2.2、v4l2_device ------------>2.2.3、v4l2_subdev ------>2.2、流程 ------>2.3、驱动实例 ------>2.4、V4L2的ioctl类型 ------------>…

Linux——进程的优先级、ACL

一、系统性能调优 Redhat7和centos7默认安装并启动了tuned服务 实验 [rootuser ~]# tuned-adm list //查看所有的调优方案 [rootuser ~]# tuned-adm recommend // 查看推荐的调优方案 virtual-guest 适用于作为虚拟机客户机运行的设备&#xff0…

Occlum原理解析及使用说明

目录 一、设计初衷 二、背景知识 1.什么是可信计算 2.什么是TEE 3.传统SGX SDK的问题 三、Occlum 1.如何使用 2.特点 3.如何使用 1.Docker部署 1 硬件支持 2 环境 3 拉取镜像创建虚机 4 简单验证 4.Occlum中gcc编译 1 交叉编译 2 初始化Occlum实例 3 Occlum构…

高效视频剪辑:批量剪辑添加srt字幕,快速制作专业视频

在视频制作过程中&#xff0c;字幕扮演着至关重要的角色&#xff0c;它们不仅能增强观众对视频内容的理解&#xff0c;还能提高视频的观感体验。然而&#xff0c;手动为每一个视频添加字幕是一项既耗时又繁琐的任务。现在有了云炫AI智剪和技巧&#xff0c;我们可以轻松地实现批…

解决git合并冲突

解决Git请求合并冲突通常涉及以下步骤&#xff1a; 了解冲突&#xff1a; 当Git在合并过程中无法自动解决文件差异时&#xff0c;它会产生冲突。 你可以通过查看Git的输出或检查冲突文件的特殊标记来识别冲突。 查看冲突文件&#xff1a; 打开Git告诉你存在冲突的文件。 你…

设计模式-07 设计模式-观察者模式(Observer Pattern)

设计模式-07 设计模式-观察者模式&#xff08;Observer Pattern&#xff09; 1.定义 观察者模式是一种软件设计模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;其中一个对象&#xff08;称为“主题”&#xff09;维护了一个依赖对象的列表&#xff08;称为“观察者”…