Databases 11 min read

Mastering Redis Transactions: When to Use MULTI/EXEC, WATCH, and DISCARD

Redis is ubiquitous in Java development for caching, ranking, and distributed locks, but its transaction model differs from traditional databases; this article explains Redis transaction fundamentals, core commands (MULTI, EXEC, DISCARD, WATCH), common pitfalls, best practices, and interview FAQs to help developers avoid mistakes.

Programmer Xu Shu
Programmer Xu Shu
Programmer Xu Shu
Mastering Redis Transactions: When to Use MULTI/EXEC, WATCH, and DISCARD

Why Care About Redis Transactions?

In daily Java development, Redis is everywhere – used for caching, leaderboards, distributed locks, and even lightweight data storage.

As business complexity grows, developers encounter three common questions:

How to guarantee atomicity of multiple Redis operations?

Are Redis transactions as reliable as MySQL transactions?

How do WATCH, MULTI, and EXEC work, and can they prevent data inconsistency under concurrency?

This article explains the essence, usage, and caveats of Redis transactions to help you avoid pitfalls.

Redis Transaction Mechanism Explained

2.1 Does Redis Support Transactions?

Conclusion: Redis supports transactions, but they are fundamentally different from MySQL transactions.

MySQL transactions emphasize ACID (Atomicity, Consistency, Isolation, Durability). Redis transactions are more like "command bundling and sequential execution" without complex isolation or rollback mechanisms.

2.2 Basic Commands and Usage

The core commands are: MULTI, EXEC, DISCARD, WATCH.

2.2.1 MULTI/EXEC – Start and Commit a Transaction

MULTI

: Begin a transaction, subsequent commands are queued. EXEC: Commit the transaction, executing queued commands in order.

Example:

# 1. Initialize stock
127.0.0.1:6379> set a:stock 100
OK
127.0.0.1:6379> set b:stock 200
OK
# 2. Start transaction
127.0.0.1:6379> multi
OK
# 3. Decrement a:stock
127.0.0.1:6379> decr a:stock
QUEUED
# 4. Decrement b:stock
127.0.0.1:6379> decr b:stock
QUEUED
# 5. Execute transaction
127.0.0.1:6379> exec
1) (integer) 99
2) (integer) 199
127.0.0.1:6379>

2.2.2 DISCARD – Abort a Transaction

If a problem is discovered after MULTI, DISCARD clears the queued commands.

2.2.3 WATCH – Optimistic Lock

In concurrent scenarios, MULTI/EXEC alone is insufficient. For example, two clients may read a balance, both decide they can transfer, and then both deduct money, causing an incorrect balance.

Use WATCH to monitor a key. If the key changes before EXEC, the transaction fails.

Example:

127.0.0.1:6379> get a:stock
"99"
127.0.0.1:6379> watch a:stock
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decr a:stock
QUEUED
127.0.0.1:6379> decr b:stock
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379>

Because a:stock was modified by another client before EXEC, the transaction returns null, indicating failure.

Common Pitfalls and Precautions

3.1 No Rollback Mechanism

Once EXEC runs, all queued commands are executed even if some later commands error; there is no automatic rollback.

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name tom
QUEUED
127.0.0.1:6379> incr name
QUEUED
127.0.0.1:6379> set age 18
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) ERR value is not an integer or out of range
3) OK
127.0.0.1:6379>

Note: an error in one command does not affect the execution of others, and no rollback occurs.

3.2 Using DISCARD to Fix Mistakes

Before EXEC, you can run DISCARD to cancel the entire transaction, ensuring none of the queued commands affect the data.

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set addr bj
QUEUED
127.0.0.1:6379> incr addr
QUEUED
127.0.0.1:6379> set code 110
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get addr
(nil)
127.0.0.1:6379>

Key points:

After EXEC, DISCARD cannot undo the transaction. DISCARD must be used before committing.

3.3 Lack of Isolation

Other clients can modify watched keys during a transaction. WATCH only monitors the specific key's value change, not complex business consistency.

Practical Tips: Correct Way to Use Redis Transactions

Prefer native atomic commands (e.g., INCR, DECR, SETNX) when possible.

Transactions guarantee only batch, sequential, one‑time execution; they do not provide isolation or rollback. WATCH is suitable for optimistic‑lock scenarios such as stock deduction or money transfer.

For complex business logic, consider Lua scripts, which execute atomically inside Redis.

Never treat Redis transactions as a replacement for database transactions; they lack ACID guarantees.

Redis Transactions vs. ACID

Atomicity : Guarantees that the whole command queue is executed atomically, but not each individual command.

Consistency : Not enforced by Redis; developers must ensure it.

Isolation : No strict isolation; other clients can modify keys during a transaction.

Durability : Depends on Redis persistence settings (RDB, AOF), unrelated to the transaction mechanism.

One‑sentence summary: Redis transactions ensure atomic execution of a batch of commands but do not provide isolation or rollback.

Interview FAQ

(1) Difference between Redis and MySQL transactions?

MySQL supports full ACID; Redis only guarantees atomic batch execution.

MySQL has rollback; Redis does not.

MySQL offers isolation levels; Redis does not.

(2) Does a failed Redis transaction roll back? No – once EXEC runs, earlier commands are not rolled back even if later commands fail.

(3) What does WATCH do? Implements an optimistic lock by monitoring a key; if the key changes before EXEC, the transaction aborts.

(4) Suitable scenarios for Redis transactions? Batch command execution and simple optimistic‑lock cases; not suitable for strong consistency or complex rollback requirements.

RedistransactionswatchexecMULTI
Programmer Xu Shu
Written by

Programmer Xu Shu

Focused on Java backend development.

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.