redis lua io.lettuce.core.RedisException: java.lang.IllegalStateException

通过reids的自增来获取一个唯一的自增id是我们的一个需求场景,不过如果使用reids的多个命令需要处理事务,于是通过lua脚本获取自增id成为了我们的首选,不过在使用lua脚本过程中我们经常会遇到如下报错

org.springframework.data.redis.RedisSystemException: Redis exception; nested exception is io.lettuce.core.RedisException: java.lang.IllegalStateException

lua脚本如下

local key = KEYS[1]
local id = redis.call('get',key)
if(id == false)
then
  redis.call('set',key,1)
  return 1
else
  redis.call('set',key,id+1)
  return id + 1
end

java 调用方法如下

package com.bsx.test.lua;

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;

/**
 * @Description:
 * @author: ztd
 * @date 2019/7/11 下午4:13
 */
@Service
@Slf4j
public class RedisIDGenerator {
    @Autowired
    private RedisTemplate<String, Long> redisTemplate;
    public Object nextIDLua(String key){
        DefaultRedisScript redisScript =new DefaultRedisScript<>();
        redisScript.setLocation(new ClassPathResource("lua/id.lua"));
        // 这个值类型要跟lua返回值类型一致才行,否则就会报 java.lang.IllegalStateException
        redisScript.setResultType(String.class);
        log.info("sha1:{}", redisScript.getSha1());
        return redisTemplate.execute(redisScript, Lists.newArrayList(key), Lists.newArrayList());
    }
}

错误原因:结果类型不对应

也许你发现了,我们lua脚本返回的内容是数字类型,而我们使用的是String类型来接收的,那么spring在把内容进行转换的过程中就报错了,解决办法很简单就是把 :

redisScript.setResultType(String.class);

改成

redisScript.setResultType(Long.class);
  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值