redisTemplate执行lua脚本报错‘for‘ initial value must be a number

1.lua脚本以及springboot代码

java 复制代码
    /**
     * 批量设置Bit位(start到end置1)
     */
    private void batchSetBit(String bitKey, long start, long end) {
        String luaScript = """
                    local key = KEYS[1]
                     local start_val = ARGV[1]
                     local end_val = ARGV[2]
                     local start_num = tonumber(start_val)
                     local end_num = tonumber(end_val)
                     local count = 0
                     for i = start_num, end_num do
                         redis.call('SETBIT', key, i, 1)
                         count = count + 1
                     end
                     return count
                """;
        DefaultRedisScript<Long> script = new DefaultRedisScript<>();
        script.setScriptText(luaScript);
        script.setResultType(Long.class);
        redisTemplate.execute(script, Collections.singletonList(bitKey), String.valueOf(start), String.valueOf(end));
    }

报错: @user_script:7: user_script:7: 'for' initial value must be a number

分析,首先修改lua脚本,打印出传递的值

java 复制代码
String luaScript = """
                    local key = KEYS[1]
                     local start_val = ARGV[1]
                     local end_val = ARGV[2]
                     local start_num = tonumber(start_val)
                     local end_num = tonumber(end_val)
                     if start_num == nil or end_num == nil then
                         return redis.error_reply("Invalid range: start=" .. tostring(start_val) .. ", end=" .. tostring(end_val))
                     end
                     local count = 0
                     for i = start_num, end_num do
                         redis.call('SETBIT', key, i, 1)
                         count = count + 1
                     end
                     return count
                """;

重新执行后报错: Invalid range: start="0", end="2999"

问题 1:Value 序列化器不兼容 Lua 脚本调用(根源问题)

你的 redisTemplate 中 valueSerializer 使用了 Jackson2JsonRedisSerializer(JSON 序列化),而 Lua 脚本需要接收纯字符串格式的数字(如 "0" "999"),但 JSON 序列化会把字符串参数包装成带引号的 JSON 字符串(比如传 "0" 会被序列化成 ""0""),导致 Lua 中 tonumber(ARGV[1]) 解析失败,这也是之前报 Invalid numeric arguments 的根本原因。

2.解决方法

(1)使用StringRedisTemplate

默认序列化器 全链路 StringRedisSerializer(纯字符串)

参数传递形式 输入 "0" → 直接转字节数组 [48](纯 UTF-8 编码)

(2)将参数的双引号去掉

bash 复制代码
    start_val = string.gsub(start_val, "^[\"']*(.-)[\"']*$", "%1")
    end_val = string.gsub(end_val, "^[\"']*(.-)[\"']*$", "%1")
相关推荐
星空露珠10 小时前
速算24点所有题库公式
开发语言·数据库·算法·游戏·lua
千寻技术帮10 小时前
10404_基于Web的校园网络安全防御系统
网络·mysql·安全·web安全·springboot
星空露珠17 小时前
速算24点检测生成核心lua
开发语言·数据库·算法·游戏·lua
想做后端的前端3 天前
Lua的热更新
开发语言·lua
金牌归来发现妻女流落街头4 天前
【Spring Boot注解】
后端·springboot
澄风4 天前
Redis ZSet+Lua脚本+SpringBoot实战:滑动窗口限流方案从原理到落地
spring boot·redis·lua
Geoking.4 天前
【Redis】Redis 中的 Pipeline 与 Lua 脚本:高性能与原子性的两种武器
redis·lua
剑之所向5 天前
嵌入式之lua脚本
开发语言·junit·lua
plmm烟酒僧5 天前
使用 Lua 进行汽车 UDS 诊断:轻量级脚本化诊断新思路
嵌入式·lua·汽车电子·uds诊断·汽车诊断·can通信·诊断协议
千寻技术帮5 天前
10368_基于SpringBoot的共享租车管理系统
源码·springboot·安装·文档·共享单车·单车租赁