Lua脚本执行redis指令报错【java.lang.IllegalStateException】

Lua脚本执行redis指令报错【java.lang.IllegalStateException】

  • 问题出现背景

    今天在学习redis时,为了让redis的多条指令(取锁、比锁、释放锁)保障原子性,我通过使用一个lua脚本统一去执行redis的的多条指令。在执行lua脚本时报错
    在这里插入图片描述

  • 问题说明

  • 问题复现
    这是我的lua脚本

     -- 获取锁的key,即: KEY_PREFIX + name
    local key = KEYS[1]
    -- 获取当前线程的标识, 即: ID_PREFIX + Thread.currentThread().getId()
    local threadId = ARGV[1]
    
    -- 获取锁中的线程标识, 对应的redis指令为: get key
    local id = redis.call('get', key)
    
    -- 判断缓存中的锁是否是当前线程的锁
    if(threadId == id) then
       -- 缓存中的锁是当前线程的锁,释放锁 del key
       return redis.call('del', key)
    end
    -- 缓存中的锁不是当前线程的锁,啥都不干
    return 0
    

    java代码

        public void unlock(){
            // 获取keys。execute可以接收多个key,它的参数类型是List,所以这里需要先转成List集合
            List<String> keys = Collections.singletonList(this.key);
            DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
            // 调用lua脚本,通过lua脚本执行redis命令来释放锁
            stringRedisTemplate.execute(redisScript , keys, this.value);
        }
    

    备注:key是当前缓存中的分布式锁对应的key,value是当前线程的锁对应的值

  • 问题结果过程

    我根据报错信息,显示排查是不是我的Lua脚本写错了,但是我确定并不是我的Lua脚本报错,于是我就将重心放在Java代码上,于是就搜索了一下,发了这个博主出现了和我类似的问题,https://blog.csdn.net/tengdazhang770960436/article/details/95653977,我就抱着试一试的态度设置了脚本执行后的返回结果的数据类型,结果就成功了。但是我仍然有疑问:我不是在创建脚本对象时,已经设置过泛型了吗?怎么还需要显示地指明脚本的返回值的数据类型?而且我在看Redis教程时,那个老师也没有设置返回值类型,这一点我就有点懵了😫
    在这里插入图片描述
    只需要在执行脚本前添加一行redisScript.setReasultType(Long.class);就成功解决了这个问题
    老师的代码,也是只指明泛型,然后就直接执行脚本,并没有指明脚本执行后返回值的类型啊?
    在这里插入图片描述

  • 问题出现的原因

    由于笔者实力较菜,目前还不能够明确为什么一定需要设置脚本的返回值类型才能让。我的猜测是可能由于我的Redis版本和老师的不太一样导致的,因为我用的是最新版的Redis6.x,而老师使用的是Redis5.x。如果有大佬知道原因,恳请留言或私信我,让我能够解惑,在下不胜感激

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知识汲取者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值