🎓 A1Learner
🔍
0 of 29 lessons completed

Sagas and Distributed Transactions

A saga is a way to finish a job that spans several services. It runs the job as a chain of small local steps, each one committed on its own service, with an undo step ready if a later step fails. A distributed transaction is the stricter alternative. All the services change together, or none of them change.

Define the problem

One database can make several changes together or not at all. That promise ends at the database boundary.

A booking job spans services. One service reserves the seat, one takes the payment, one books the room, and one sends the confirmation.

Each service owns its own data. If the room booking fails after the payment lands, the customer has paid for a trip that does not exist.

The job needs an all-or-nothing feel across services that share no database. Two designs answer that need, and they trade very differently.

The distributed transaction

A distributed transaction stretches the database promise across services. One coordinator runs the agreement.

First the coordinator asks every service to prepare. Each service does its part of the work, holds it uncommitted, locks the data it touched, and answers ready or not ready.

If every service answers ready, the coordinator tells them all to commit. If any service cannot prepare, the coordinator tells them all to abandon the work.

The weakness is the waiting. Prepared services hold locks and cannot finish until the coordinator decides, so a coordinator that fails mid-agreement leaves services frozen with it.

Long agreements across distant services stretch that wait further. The design buys certainty with other people's availability.

The saga

A saga gives up the single agreement. It splits the job into a chain of small steps, and each step is an ordinary local transaction on its own service.

Each step commits as soon as it finishes. The seat is really reserved, the payment is really taken, and the world can see each result at once.

One service can lead the chain, sending each step in turn and recording progress as it goes. Or each finished step can announce itself, and the next service reacts to the announcement.

The saga's record of which steps have finished must be durable. It is kept in a write-ahead log or a database, so a crashed leader can resume the chain instead of guessing.

When a step fails, the saga stops moving forward. It starts moving backward instead, undoing the steps that already committed.

Compensating actions

A compensating action is an action that undoes the effect of a finished step, in the terms of the job itself. It releases the seat, refunds the payment, or cancels the room.

It is not a rollback of stored bytes. The payment really happened, and the refund is a new, real event that balances it.

Compensations run in reverse order, last finished step first. Each one is retried until it lands, using idempotency so a retry never refunds twice.

Some steps cannot be undone. A sent confirmation message cannot be unsent, so well-built sagas put the un-undoable step last, after every step that might fail.

The arithmetic explains why this machinery matters. Take a stated demo where 1 step in 1,000 fails, and a saga has 10 steps.

1,000,000 sagas × 10 steps = 10,000,000 steps, and at 1 failure per 1,000 steps that is 10,000,000 ÷ 1,000 = 10,000 failed steps.

So roughly 10,000 sagas in every million need their compensating actions. Compensation is not an edge case. It is a normal path, and it is designed like one.

Where sagas break

A saga has no hiding place mid-flight. Other readers see the half-finished job, a paid booking with no room, until the chain completes or compensates.

Applications must tolerate those states. A screen that shows the booking should show it as pending, not as broken or as final.

Compensating actions can fail too. A refund service that is down leaves the saga paused mid-undo, and operators need a way to see and prod stuck sagas.

Two sagas can also trip over each other. With no locks held between steps, two chains touching the same seat must settle the clash by their own rules.

Trade-offs and wrap-up

The distributed transaction gives a clean promise and takes availability as payment. It suits short agreements among services that are close and controlled together.

The saga gives availability and scale, and takes on visible half-finished states and hand-written undo steps as payment. It suits long jobs across services owned by different teams.

The main idea is the exchange itself. Across services, all-or-nothing stops being free. A design either blocks everyone until all agree, or commits step by step and learns to undo.

Distributed transaction vs saga

QuestionDistributed transactionSaga
When do changes appear?All at onceStep by step
If a late step failsEverything rolls backCompensating actions run
While it runsServices wait, lockedServices stay free
What readers seeNothing until it endsHalf-finished states

Exercise

A saga's third step fails after the first two steps have already committed on their services. What happens next?