What Is the Saga Pattern?
The saga pattern is a way to keep data consistent across multiple services without using a single distributed transaction. Instead of locking several systems together, a saga breaks a business process into a sequence of local transactions — each one updating a single service and triggering the next step. If a step fails, the saga runs compensating transactions that undo the work already done, returning the overall process to a consistent state.
It is most associated with microservices, where each service owns its own database and a traditional cross-service transaction is impractical.
How a Saga Works
Each step of a saga commits locally and then signals the next step, usually by publishing an event or sending a command. The catch is that a committed local transaction cannot be rolled back later — so instead of rollback, a saga relies on compensating transactions: operations that semantically reverse a completed step. You cannot un-commit a payment, but you can issue a refund; you cannot un-reserve stock, but you can release it. If the fourth step fails, the saga invokes the compensations for steps three, two, and one, in reverse order.
This is what separates a saga from an atomic transaction: there is no isolation, so intermediate states are briefly visible to the rest of the system, and consistency is eventual rather than immediate.
Orchestration vs Choreography
Sagas are coordinated in one of two styles:
- Choreography. There is no central controller. Each service listens for events and reacts by doing its local work and publishing its own event. This is simple for short flows but gets hard to follow as the number of steps grows.
- Orchestration. A central orchestrator tells each service which local transaction to run, tracks progress, and triggers compensations on failure. It centralizes the logic, which makes complex, many-step flows easier to manage and observe — at the cost of an extra moving part.
Saga vs Two-Phase Commit
The saga pattern is the main alternative to two-phase commit and XA. Two-phase commit delivers strict, immediate atomicity but is synchronous and blocking, holding locks across systems until everyone agrees. A saga gives up that strict isolation in exchange for availability and scale: services stay loosely coupled and never block one another, accepting eventual consistency and the work of designing compensations. Reach for 2PC when a wrong intermediate state is unacceptable; reach for a saga when availability and throughput matter more.
Sagas with Valkey and Redis
Redisson does not provide a saga framework — for strict, ACID-style distributed transactions it offers the XA and two-phase commit route instead. But Valkey and Redis are a natural fit for the infrastructure a saga runs on. Redis Streams, exposed in Java through Redisson, make a reliable event backbone for connecting saga steps in either choreography or orchestration; Redisson maps and buckets are commonly used to hold orchestrator state and idempotency keys so that duplicate event deliveries are handled safely; and Redisson distributed locks help enforce the semantic locks a saga sometimes needs.
For Valkey and Redis transactions themselves — including the XA approach that complements sagas — see How to Manage Transactions in Valkey and Redis on Java.