Bobcares

How to Fix “redis err exec without multi” in Spring Redis

PDF Header PDF Footer

Fix the common Spring Redis error: redis err exec without multi. Our Live Support Team is ready to assist.

How to Fix “redis err exec without multi” in Spring Redis

redis err exec without multiEncountering the redis err exec without multi exception can be puzzling, especially when multi() is clearly used in the code. This error often occurs when attempting to use Redis transactions with Spring Data Redis. The stack trace usually points to:

 

io.lettuce.core.RedisCommandExecutionException: ERR EXEC without MULTICopy Code

At first glance, the code may appear correct:

redisTemplate.opsForHash().put("customer001", "salary", "5000");
redisTemplate.watch("customer001");
redisTemplate.multi();
redisTemplate.opsForHash().put("customer001", "age", "20");
redisTemplate.exec();Copy Code

However, despite calling multi(), Redis responds with redis err exec without multi. The issue lies in how Spring Redis manages connections during transactional operations.

Why This Error Happens

Spring Data Redis disables transaction support by default. Looking into the RedisTemplate source reveals the following:

public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
private boolean enableTransactionSupport = false;
}Copy Code

To enable transactions, the following method is often added:

redisTemplate.setEnableTransactionSupport(true);Copy Code

Updated code:

redisTemplate.opsForHash().put("customer001", "salary", "5000");
redisTemplate.setEnableTransactionSupport(true);
redisTemplate.watch("customer001");
redisTemplate.multi();
redisTemplate.opsForHash().put("customer001", "age", "20");
redisTemplate.exec();Copy Code

Yet, even after setting enableTransactionSupport to true, the same exception can persist.

The Solution: Use SessionCallback

The actual fix requires the use of SessionCallback. This ensures that all operations, watch, multi, and exec, run on the same Redis connection. Here’s the correct approach:

redisTemplate.execute(new SessionCallback<List<Object>>() {
@Override
public <K, V> List<Object> execute(RedisOperations<K, V> operations) throws DataAccessException {
redisTemplate.opsForHash().put("customer001", "salary", "5000");
redisTemplate.watch("customer001");
redisTemplate.multi();
redisTemplate.opsForHash().put("customer001", "age", "20");
return redisTemplate.exec();
}
});Copy Code

This resolves the issue effectively by keeping the transaction within a single connection context and avoids issues like redis error socket closed unexpectedly.

[If needed, Our team is available 24/7 for additional assistance.]

Important Note for Redis Cluster Users

The above solution applies to Redis standalone mode only. Redis cluster mode does not support the WATCH command. In such cases, Lua scripts should be used to maintain atomic operations without relying on transaction commands like watch or multi.

Conclusion

The redis err exec without multi error is typically caused by connection inconsistencies or disabled transactional support in Spring Redis. While enabling transaction support may seem like the fix, it’s not enough. Wrapping the logic inside a SessionCallback is the reliable way to ensure proper Redis transaction handling.

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

Get featured on the Bobcares blog and share your expertise with a global tech audience.

WRITE FOR US
server management

Spend time on your business, not on your servers.

TALK TO US

Or click here to learn more.

Speed issues driving customers away?
We’ve got your back!