Why Does Redis Increment Return Null in Spring @Transactional? Root Cause and Fix
This article analyzes why Redis's increment operation returns null when used inside a Spring @Transactional method with transaction support enabled, details the debugging steps, experiments, and presents two practical solutions to prevent the issue.
Introduction
In a production environment, customer service staff encountered a recurring failure when creating service events each morning. The failure was resolved temporarily by restarting the microservice, after which the creation succeeded until the next morning.
Problem Description
The service creates a distributed ID for each event using Redis's
incrementoperation:
<code>return redisTemplate.opsForValue().increment("count", 1);</code>Every morning the
incrementcall returned
null, causing the subsequent logic to fail. Restarting the microservice restored normal behavior.
Investigation
2.1 First Hypothesis – Connection Leak
It was suspected that a large number of jobs at night left many Redis connections unclosed, causing the morning operation to fail. However, other Redis‑using features worked fine, so this hypothesis was discarded.
2.2 Second Hypothesis – Redis Transaction
Redis documentation states that
incrementreturns
nullwhen used inside a pipeline or a transaction. The service implementation class is annotated with
@Transactional, which might affect the Redis call.
2.3 Verifying the Transaction Hypothesis
A table of test cases showed that when
@Transactionalis present, the Redis increment returns
null. A demo program without the annotation always returned a valid number, confirming that the annotation alone does not cause the issue.
2.4 Third Hypothesis – Redis Transaction Support Enabled
Another developer had enabled Redis transaction support and used
multi/
execin nightly jobs. Enabling transaction support causes Redis commands to be queued, and
incrementreturns
nulluntil the transaction is committed.
2.5 Experimental Verification
Four scenarios were tested:
Enable Redis transaction support and execute
incrementinside a
@Transactionalmethod –
nullreturned.
Enable Redis transaction support and execute
incrementin a non‑transactional method – valid result.
Disable transaction support – always valid result.
The experiments confirmed that only the combination of Redis transaction support and Spring
@Transactionalcaused the
nullreturn.
Root Cause Analysis
When
setEnableTransactionSupport(true)is set, Spring binds a Redis connection to the current transaction. The call to
incrementis then executed inside a Redis
MULTIblock, which queues the command and returns
nullimmediately. After the Spring transaction commits, the queued commands are executed, and the key value is incremented, but the original call has already returned
null.
Solutions
Solution 1 – Disable Transaction Support After Use
Manually turn off Redis transaction support after each transactional operation. This approach works but can still produce
nullif a Redis command is executed inside a
@Transactionalmethod while the transaction support is active.
Solution 2 – Separate RedisTemplate Beans
Create two
StringRedisTemplatebeans:
stringRedisTemplate– without transaction support, used for normal commands.
stringRedisTemplateTransaction– with transaction support, used only for explicit Redis transactions.
Inject the appropriate bean where needed. This isolates transactional Redis usage from regular Redis operations, ensuring that
incrementreturns the expected value inside Spring
@Transactionalmethods.
Implementation Example
Define a configuration class that declares both beans, then inject them into services accordingly. The demo showed that after applying the second solution, the Redis increment operation consistently returned the correct count.
Conclusion
Enabling Redis transaction support together with Spring's
@Transactionalcauses Redis commands to be queued, leading to
nullreturns for increment operations. Using separate RedisTemplate instances or disabling transaction support after use resolves the issue.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.