Closed
Description
I have a piece of code:
stringRedisTemplate.execute((RedisCallback<Void>) connection -> {
connection.multi();
///some logic
connection.exec();
}
And timeout occurs on MULTI call:
"exception":{
"message":"Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s)",
"stackTrace":"org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s)
\tat org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:70)
\tat org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:41)
\tat org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44)
\tat org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:42)
\tat org.springframework.data.redis.connection.lettuce.LettuceConnection.convertLettuceAccessException(LettuceConnection.java:277)
\tat org.springframework.data.redis.connection.lettuce.LettuceConnection.multi(LettuceConnection.java:659)
\tat org.springframework.data.redis.core.RedisTemplate.lambda$multi$23(RedisTemplate.java:1032)
\tat org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:224)
\tat org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:191)
\tat org.springframework.data.redis.core.RedisTemplate.multi(RedisTemplate.java:1031)
After that, any following MULTI invocation fails with the following exception:
RedisCommandExecutionException: ERR MULTI calls can not be nested
I was able to reproduce it with a live redis instance using redis-cli CLIENT PAUSE
to simulate a timeout in redis.
Workaround:
I surrounded it with try/catch to call DISCARD manually:
stringRedisTemplate.execute((RedisCallback<Void>) connection -> {
try {
connection.multi();
///some logic
connection.exec();
} catch(QueryTimeoutException e) {
connection.discard():
}
Actually, I expected that it would not help if DISCARD failed because of the timeout, but even if the timeout happens DICARD rollbacks transaction somehow.
My env:
Java version: 17.0.9
spring-data-redis version: 2.7.15
redis version:3.2.12