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(ARGV1) 解析失败,这也是之前报 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")
相关推荐
带刺的坐椅6 天前
Spring Boot → Solon 注解迁移实战指南:一张对照表说清楚
java·springboot·web·solon
十五喵源码网16 天前
基于springboot2+vue2的租房管理系统
java·毕业设计·springboot·论文笔记
xingpanvip16 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
骇客之技术16 天前
AutoLua:在安卓上写 Lua 脚本
android·junit·lua
weixin_4713830316 天前
Node.js + Express 入门实战笔记-01-基础
node.js·lua·express
whaledown16 天前
Kafka 与 Java 消息队列入门:用订单场景理解核心机制
java·kafka·消息队列·springboot
闪电悠米16 天前
黑马点评-Redis ZSet-实现关注 Feed 流
服务器·网络·数据库·redis·缓存·junit·lua
二哈赛车手17 天前
新人笔记---最终版智能体图片分析完整方案,包括一些总结于经验,以及各种优化点讲解
java·笔记·spring·ai·springboot
十五喵源码网17 天前
基于SpringBoot2+vue2的酒店客房管理系统
java·毕业设计·springboot·论文笔记
Chris-zz17 天前
lua流程控制
开发语言·lua