Two-phase commit tries to make several services act as one database. A saga gives up on that. It accepts that each service commits on its own, straight away, and plans in advance how to repair things if a later step fails.
The idea comes from a 1987 database paper about long-running transactions, the kind that would hold locks for far too long if done in one piece. Microservices brought it back, because "a change that spans services and can take minutes" is exactly what checkout is.
The idea
A saga is a sequence of local transactions, one per step, where each step that might need undoing has a compensating transaction that reverses its effect in business terms.
Each step runs in one service, in that service's own database, and commits immediately. No locks are held across services. If every step succeeds, the saga is done. If step 4 fails, the saga runs the compensations for steps 3, 2 and 1, in reverse order.
Success: T1 -> T2 -> T3 -> T4 done
Failure: T1 -> T2 -> T3 -> T4 fails -> C3 -> C2 -> C1 cancelled cleanly
Notice what you're giving up. Between T1 and T4, the system is partly done, and other requests can see that. A saga is atomic only in the sense that it eventually ends up all done or all undone. It is not isolated. We'll deal with that later in this module.