Why Does Redis Increment Return Null Inside @Transactional? The Hidden Interaction Explained

This article investigates a production issue where Redis increment operations return null each morning, explores hypotheses about Redis pipelines, transactions, and Spring @Transactional interaction, reproduces the bug, analyzes the source code, and proposes two practical solutions to prevent null returns.

Sanyou's Java Diary
Sanyou's Java Diary
Sanyou's Java Diary
Why Does Redis Increment Return Null Inside @Transactional? The Hidden Interaction Explained

1. Introduction

A production environment exhibited a strange problem: every morning, creating a customer service event in the backend failed because the Redis increment operation returned null. Restarting the microservice restored normal behavior, but the issue reappeared the next morning.

2. Investigation

We first examined why Redis increment could return null. The code used was:

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

Two main hypotheses were considered:

2.1 Hypothesis 1

Heavy jobs at night might leave many Redis connections unreleased, causing failures in the morning. However, other Redis‑using features worked fine, so this hypothesis was discarded.

2.2 Hypothesis 2

The issue might be related to Redis transactions. The official Redis documentation states that increment returns null when used inside a pipeline or a transaction.

Transaction provides a way to batch multiple commands and execute them atomically.

We noticed that the service implementation class was annotated with @Transactional, suggesting a possible impact.

2.3 Verifying Hypothesis 2

A table showed that when @Transactional was omitted, the increment command returned a normal value. We built a demo controller and service to test this.

Running the API via Postman showed the count incremented correctly without returning null, disproving the hypothesis that @Transactional alone caused the issue.

2.4 Hypothesis 3

A colleague had recently added Redis transaction support to a nightly job. The simplified code enabled transaction support with setEnableTransactionSupport.

Can enabling Redis transactions affect Spring‑managed transactions?

2.5 Verifying Hypothesis 3

We created two scenarios:

Scenario 3: Enable Redis transaction support and execute the increment inside a method annotated with @Transactional.

Scenario 4: Enable Redis transaction support but execute the increment in a method without @Transactional.

In Scenario 3, every increment call returned null while the actual Redis key still increased. In Scenario 4, the increment returned the expected value.

The conclusion: when Redis transaction support is enabled, any Redis command executed inside a Spring @Transactional method is treated as part of a Redis transaction, queued, and thus returns null until the transaction is committed.

3. Source Code Analysis

The core method execute in RedisTemplate binds a connection when transaction support is on, invoking conn.multi() to start a Redis transaction.

Consequently, the increment command is queued and yields null as the immediate result.

4. Fixes

Two solutions were proposed:

After each Redis transaction, explicitly disable transaction support before executing normal Redis commands. This approach has drawbacks if a transaction is still active.

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

Implementation details and configuration snippets were provided to illustrate both approaches. The second solution successfully prevented null returns in the problematic scenario.

Additional note: unreleased Redis connections can cause similar issues, which will be covered in a future discussion.

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.

Backend DevelopmentredisspringtransactionalRedis Transaction
Sanyou's Java Diary
Written by

Sanyou's Java Diary

Passionate about technology, though not great at solving problems; eager to share, never tire of learning!

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.