Redis 执行 Lua 脚本抛出 StatusOutput does not support set(long) 异常
Redis Lua Spring Boot About 5,287 words异常信息
Caused by: org.springframework.data.redis.RedisSystemException: Unknown redis exception; nested exception is java.lang.IllegalStateException: io.lettuce.core.output.StatusOutput does not support set(long)
at org.springframework.data.redis.FallbackExceptionTranslationStrategy.getFallback(FallbackExceptionTranslationStrategy.java:53) ~[spring-data-redis-2.4.5.jar:2.4.5]
at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:43) ~[spring-data-redis-2.4.5.jar:2.4.5]
at org.springframework.data.redis.connection.lettuce.LettuceConnection.convertLettuceAccessException(LettuceConnection.java:272) ~[spring-data-redis-2.4.5.jar:2.4.5]
at org.springframework.data.redis.connection.lettuce.LettuceScriptingCommands.convertLettuceAccessException(LettuceScriptingCommands.java:236) ~[spring-data-redis-2.4.5.jar:2.4.5]
at org.springframework.data.redis.connection.lettuce.LettuceScriptingCommands.evalSha(LettuceScriptingCommands.java:195) ~[spring-data-redis-2.4.5.jar:2.4.5]
at org.springframework.data.redis.connection.DefaultedRedisConnection.evalSha(DefaultedRedisConnection.java:1530) ~[spring-data-redis-2.4.5.jar:2.4.5]
at org.springframework.data.redis.connection.DefaultStringRedisConnection.evalSha(DefaultStringRedisConnection.java:1776) ~[spring-data-redis-2.4.5.jar:2.4.5]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_151]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_151]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_151]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_151]
at org.springframework.data.redis.core.CloseSuppressingInvocationHandler.invoke(CloseSuppressingInvocationHandler.java:61) ~[spring-data-redis-2.4.5.jar:2.4.5]
at com.sun.proxy.$Proxy67.evalSha(Unknown Source) ~[na:na]
at org.springframework.data.redis.core.script.DefaultScriptExecutor.eval(DefaultScriptExecutor.java:77) ~[spring-data-redis-2.4.5.jar:2.4.5]
at org.springframework.data.redis.core.script.DefaultScriptExecutor.lambda$execute$0(DefaultScriptExecutor.java:68) ~[spring-data-redis-2.4.5.jar:2.4.5]
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:222) ~[spring-data-redis-2.4.5.jar:2.4.5]
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:189) ~[spring-data-redis-2.4.5.jar:2.4.5]
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:176) ~[spring-data-redis-2.4.5.jar:2.4.5]
at org.springframework.data.redis.core.script.DefaultScriptExecutor.execute(DefaultScriptExecutor.java:58) ~[spring-data-redis-2.4.5.jar:2.4.5]
at org.springframework.data.redis.core.script.DefaultScriptExecutor.execute(DefaultScriptExecutor.java:52) ~[spring-data-redis-2.4.5.jar:2.4.5]
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:343) ~[spring-data-redis-2.4.5.jar:2.4.5]
at com.example.cache.CacheApplication.run(CacheApplication.java:29) [classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795) [spring-boot-2.4.3.jar:2.4.3]
... 5 common frames omitted
异常代码
private static final String UNLOCK_LUA_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
private static final Integer UNLOCK_SUCCESS_RESULT = 1;
public boolean unlock(String key, String value) {
Integer result = stringRedisTemplate.execute(RedisScript.of(UNLOCK_LUA_SCRIPT, Integer.class), Collections.singletonList(key), value);
return UNLOCK_SUCCESS_RESULT.equals(result);
}
原因
Redis
中的integer
对应Java
中的Long
。
public enum ReturnType {
/**
* Returned as Boolean
*/
BOOLEAN,
/**
* Returned as {@link Long}
*/
INTEGER,
/**
* Returned as {@link List<Object>}
*/
MULTI,
/**
* Returned as {@literal byte[]}
*/
STATUS,
/**
* Returned as {@literal byte[]}
*/
VALUE;
/**
* @param javaType can be {@literal null} which translates to {@link ReturnType#STATUS}.
* @return never {@literal null}.
*/
public static ReturnType fromJavaType(@Nullable Class<?> javaType) {
if (javaType == null) {
return ReturnType.STATUS;
}
if (ClassUtils.isAssignable(List.class, javaType)) {
return ReturnType.MULTI;
}
if (ClassUtils.isAssignable(Boolean.class, javaType)) {
return ReturnType.BOOLEAN;
}
if (ClassUtils.isAssignable(Long.class, javaType)) {
return ReturnType.INTEGER;
}
return ReturnType.VALUE;
}
}
修改代码
将Integer
改为Long
:
private static final String UNLOCK_LUA_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
private static final Long UNLOCK_SUCCESS_RESULT = 1L;
public boolean unlock(String key, String value) {
Long result = stringRedisTemplate.execute(RedisScript.of(UNLOCK_LUA_SCRIPT, Long.class), Collections.singletonList(key), value);
return UNLOCK_SUCCESS_RESULT.equals(result);
}
Views: 11,757 · Posted: 2021-03-18
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...