Investigation and Resolution of Redis Increment Returning Null under Spring @Transactional

This article analyzes why a Redis increment operation returns null when executed inside a Spring @Transactional method, explores several hypotheses with experiments, explains the underlying Redis transaction behavior, and proposes two practical solutions to prevent the issue in production environments.

Wukong Talks Architecture
Wukong Talks Architecture
Wukong Talks Architecture
Investigation and Resolution of Redis Increment Returning Null under Spring @Transactional

1. Introduction

The production environment exhibited a recurring problem where creating a customer service event each morning failed, but restarting the microservice restored normal operation. The failure was traced to a Redis increment operation returning null when generating a distributed ID.

2. Investigation

2.1 Hypothesis 1

It was initially suspected that a large number of jobs at night left many Redis connections unreleased, causing the morning failure. However, other Redis‑using features worked fine, so this hypothesis was discarded.

2.2 Hypothesis 2

The next guess involved Redis transactions. The official RedisTemplate documentation states that increment returns null when used inside a pipeline or a transaction.

return redisTemplate.opsForValue().increment("count", 1);

A @Transactional annotation on the service class raised the question of whether it affected Redis commands.

2.3 Verifying Hypothesis 2

A demo showed that when the service method was annotated with @Transactional but Redis transaction support was disabled, the increment returned a normal value, disproving the hypothesis.

2.4 Hypothesis 3

Another developer had enabled Redis transaction support for a nightly job. Enabling setEnableTransactionSupport could cause the observed null returns.

2.5 Verifying Hypothesis 3

Four test scenarios were created:

Enable Redis transaction support and execute multi / exec.

Scenario 3: Execute the increment inside a @Transactional method.

Scenario 4: Execute the increment in a non‑transactional method.

2.5.1 Executing Redis Transaction

Using multi and exec successfully set two keys.

2.5.2 Increment inside @Transactional

When the increment was called from a @Transactional method with Redis transaction support enabled, the result was repeatedly null, reproducing the production issue, although the actual key value in Redis still increased.

In contrast, the same operation in a non‑transactional method returned the expected incremented value.

3. Source Code Analysis

The core execute method of RedisTemplate binds a connection when transaction support is on, leading to the use of conn.multi() and queuing commands. Consequently, the increment command returns null until the transaction is committed.

stringRedisTemplate.opsForValue().increment("count", 1);

After a service restart, transaction support resets to the default (disabled), and the increment works normally again.

4. Fixes

Two solutions were proposed:

After each Redis transaction, explicitly disable transaction support before executing normal Redis commands (has drawbacks if transactions overlap).

Create two StringRedisTemplate beans: one with transaction support for transactional jobs, and another without for regular operations. The configuration injects the appropriate bean where needed.

Implementation details and configuration snippets were provided, and the second approach successfully eliminated the null returns.

Additional notes mention a potential connection‑leak issue when Redis transactions are used, which will be addressed in future work.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaspringTransactional
Wukong Talks Architecture
Written by

Wukong Talks Architecture

Explaining distributed systems and architecture through stories. Author of the "JVM Performance Tuning in Practice" column, open-source author of "Spring Cloud in Practice PassJava", and independently developed a PMP practice quiz mini-program.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.