What Is a Valkey & Redis Transaction?
In Valkey and Redis, a transaction is a way to group several commands so they run as a single, isolated step: once a transaction starts executing, no other client's commands can interleave with it, and the grouped commands run in order from first to last.
Natively, Valkey and Redis build transactions from four commands. MULTI begins a transaction and queues the commands that follow it; EXEC runs the whole queue as one isolated unit; DISCARD throws the queue away before it runs; and WATCH adds optimistic locking, aborting the transaction if a watched key changes before EXEC.
Not every guarantee needs a transaction. Many individual Valkey and Redis commands are themselves atomic operations — INCR, SETNX, and GETSET, among others, each run as a single indivisible step that no other client can observe halfway through. When one atomic command expresses what you need, it is simpler and faster than opening a transaction; transactions earn their place once several operations must succeed or fail together.
Atomicity, with an Important Caveat
A native Valkey or Redis transaction is not atomic in the way a relational database transaction is. The "all or nothing" guarantee applies only at queue time — if a command can't be queued, the whole transaction is discarded before anything runs. But once EXEC begins, a command that fails at runtime does not undo the others: the remaining commands still execute, and there is no ROLLBACK to restore the previous state. DISCARD only helps before EXEC; it cannot reverse commands that have already run.
This matters most for multi-step business logic — transfers, inventory updates, or any change spanning several keys — where a half-applied result is a real problem.
Transactions in Redisson
Redisson, the Valkey and Redis Java client, provides a higher-level transaction API that behaves the way Java developers expect. Its RTransaction operates over distributed objects such as RMap, RSet, and RBucket, holding all modifications until you commit. Because nothing is finalized until commit(), a rollback() cleanly discards pending changes — giving the genuine rollback that native transactions lack. Redisson transactions run at READ_COMMITTED isolation and integrate with Spring's transaction manager and, for distributed transactions across multiple systems, with XA transactions through JTA.
For a full guide with code examples, see How to Manage Transactions in Valkey and Redis on Java.