System Design · Architecture under constraints

How do distributed transactions work and why are they hard?

Harddistributed transactionstwo-phase commitconsistencyUpdated Oct 2026
Quiz this track

Short answer

Distributed transactions coordinate a commit across independent services. Two-phase commit is correct under strict assumptions but blocks on coordinator failure; sagas and outboxes trade atomicity for availability.

A local transaction is easy because one database owns the commit point. Across services, there is no shared transaction manager, and a network failure can leave one participant committed and another not. The design question is how to make that partial state recoverable and visible.

The main approaches

  • Two-phase commit: a coordinator asks all participants to prepare, then tells them to commit or abort
  • Three-phase commit: adds a pre-commit phase to reduce blocking, at the cost of more messages and assumptions about bounded delays
  • Try-confirm-cancel: reserve resources in a try phase, confirm on success, cancel on failure, with idempotent reservations
  • Saga: a sequence of local transactions with compensating actions for rollback
  • Transactional outbox: commit state and the event to be published in one local transaction, then relay it

Two-phase commit is the strongest and most misunderstood. If the coordinator fails after participants have prepared but before it sends the decision, participants hold locks and cannot safely commit or abort alone. They block until the coordinator recovers. It also requires every participant to support the protocol and to keep prepared state durable.

Even with a correct commit protocol, isolation is weaker than in a single database. A saga exposes intermediate states to other readers, so a seat may appear taken before payment completes. Semantic locks, pending states and idempotent compensation reduce the harm, but they do not provide serializability.

Avoid distributed transactions by changing the boundary. Keep the invariant inside one service and one database when possible. If the workflow truly spans services, accept eventual consistency and design the user-visible pending and failure states explicitly.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1Why does two-phase commit block when the coordinator fails?
  2. 2When is try-confirm-cancel preferable to a saga?
  3. 3What is the difference between atomicity and isolation across services?
  4. 4How would you avoid a distributed transaction at the design stage?

Say it in the interview

Distributed transactions try to preserve atomicity across independent services, and two-phase commit does that by preparing everyone before a single commit decision. Its weakness is blocking: if the coordinator dies after prepare, participants hold locks and must wait. Sagas and outboxes avoid that by accepting intermediate states and eventual consistency. I try to keep the invariant inside one service first, because that removes the problem instead of managing it.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live System Design mock interview and get scored feedback on depth, clarity and confidence.