Lesson 12 of 19
17. Transactions and Locking

17.11 What is a saga?

3 min read+10 XP

On the train: Instead of one coordinator holding everyone, the journey is booked step by step: reserve the seat, then charge the card, then order the meal. If the meal fails, you undo what was done, newest first: refund the card, release the seat.

In the system: A saga splits a cross-service transaction into local transactions, each committed on its own, with a compensating action for each step:

hold seat, charge card, issue ticket; the ticket fails, so refund and release in reverse.

Figure: each step commits on its own; a failure runs the undo steps backwards.

For the signing: (1) hold the seat in the seat service; (2) charge ₹499 in the payment service; (3) issue the ticket in the ticket service. If step 3 fails, run refund ₹499, then release seat. In the chapter's code, a saga whose third step fails ends with the ledger back to empty and the log showing the refund before the release.

Two styles:

  • Orchestration: one coordinator service tells each service what to do next. Easier to follow and debug.
  • Choreography: each service listens for events and reacts ("payment succeeded" → issue ticket). Less central control, harder to trace (events in Chapter 23, tracing in Chapter 30).

What sagas give up: isolation. Between steps, others can see a half-finished state ("seat held, card charged, no ticket yet"). Design for it: mark things as pending, make every step and compensation safe to retry (idempotent, Chapter 24), and remember that some actions can't be undone (an email already sent), so put them last.

Memory code: "Do it step by step, and keep an undo for every step."