Redis - Transactions
Redis - Transactions
Section titled “Redis - Transactions”Redis transactions allow you to execute a block of commands as a single, atomic operation. This ensures that no other client can interrupt the execution of the command sequence.
Properties of Redis Transactions
Section titled “Properties of Redis Transactions”- Serial Execution: All commands within a transaction are serialized and executed sequentially. Once an
EXECcommand is triggered, Redis will not serve any other client’s requests until the transaction is complete. - Atomicity (with a caveat): Transactions are atomic. This means either all commands in the block are executed, or none are (in case of a syntax error before
EXEC). However, Redis does not support rollbacks. If a command fails at runtime (e.g., trying toINCRa non-integer value), the transaction will continue, and all prior successful commands will remain committed.
The Core Commands: MULTI and EXEC
Section titled “The Core Commands: MULTI and EXEC”A transaction is initiated with the MULTI command. After MULTI, the client can send multiple commands. These commands are not executed immediately but are queued by Redis. The transaction is finally triggered by the EXEC command.
Example: Atomic Increment and Set
Section titled “Example: Atomic Increment and Set”# Start a transaction127.0.0.1:6379> MULTIOK
# Queue a command to set a user's name. Redis replies with QUEUED.127.0.0.1:6379> SET user:1:name "Carol"QUEUED
# Queue a command to increment the user's login count.127.0.0.1:6379> INCR user:1:loginsQUEUED
# Execute the transaction. Redis runs both commands and returns their results.127.0.0.1:6379> EXEC1) OK2) (integer) 1Conditional Transactions: WATCH
Section titled “Conditional Transactions: WATCH”WATCH provides a check-and-set (CAS) mechanism. If you WATCH a key, the transaction will only execute if that key has not been modified by another client since it was watched. If it was modified, the EXEC command will fail, returning a nil reply, and the client can retry the operation.
Example: Optimistic Locking
Section titled “Example: Optimistic Locking”Imagine two clients trying to update a product’s inventory at the same time.
# Initial state: inventory is 10127.0.0.1:6379> SET product:123:inventory 10OK
# --- Client A starts ---127.0.0.1:6379> WATCH product:123:inventoryOK127.0.0.1:6379> MULTIOK127.0.0.1:6379> DECRBY product:123:inventory 2QUEUED
# --- Before Client A can EXEC, Client B quickly buys 1 item ---# --- Client B's session (executes immediately) ---# 127.0.0.1:6379> DECR product:123:inventory# (integer) 9# --- Client B is done ---
# --- Now, Client A tries to execute its transaction ---127.0.0.1:6379> EXEC(nil) # The transaction fails because the watched key was changed.
# Client A's application logic should now detect the nil reply,# re-fetch the inventory, and retry the whole WATCH/MULTI/EXEC sequence.All Transaction Commands
Section titled “All Transaction Commands”| Command | Description |
|---|---|
| MULTI | Marks the start of a transaction block. Subsequent commands are queued. |
| EXEC | Executes all commands queued after MULTI. |
| DISCARD | Flushes all commands queued after MULTI, exiting the transaction. |
| WATCH key [key …] | Monitors given keys. If any are modified before EXEC, the transaction aborts. |
| UNWATCH | Flushes all keys that are being watched. |
Common Pitfalls and Alternatives
Section titled “Common Pitfalls and Alternatives”- No Runtime Rollback: Remember, if a command like
INCRfails on a string value duringEXEC, previous commands in the transaction (like aSET) are not rolled back. Your application must handle this possibility. - Syntax Errors: If a command has a syntax error (e.g.,
SETTinstead ofSET), modern Redis versions will abort the entire transaction uponEXEC. - Alternative: Lua Scripts: For complex atomic operations that require server-side logic, Redis Lua scripting is often a more powerful and flexible alternative to
WATCH/MULTI/EXEC. A script is always executed atomically.