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 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);

你可能感兴趣的:(18_nosql)