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")
相关推荐
Flittly2 天前
【SpringAIAlibaba新手村系列】(15)MCP Client 调用本地服务
java·笔记·spring·ai·springboot
小李云雾2 天前
FastAPI 后端开发:文件上传 + 表单提交
开发语言·python·lua·postman·fastapi
曼巴UE52 天前
Unlua 官方案例
c++·ue5·lua·ue
列星随旋3 天前
基于 Redis + Lua,实现“多维度原子限流”(令牌桶 + 滑动窗口)
java·redis·lua
上海合宙LuatOS3 天前
LuatOS扩展库API——【exgnss】GNSS定位
物联网·lua·luatos
0xDevNull3 天前
Redis Lua 脚本详细教程
redis·缓存·lua
上海合宙LuatOS3 天前
LuatOS扩展库API——【exlcd】显示屏控制
物联网·lua·luatos
0xDevNull3 天前
Spring Boot 中使用 Redis Lua 脚本详细教程
spring boot·redis·lua
可以简单点4 天前
分析一个线程日志工具类
java·springboot
鬼先生_sir4 天前
SpringBoot-基础面试篇
java·springboot·java面试