100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

What are Distributed Transactions and How Do They Work?

Learn how distributed transactions work, two-phase commit versus the Saga pattern, and when to use compensating actions.

hardQ182 of 224 in System Design Est. time: 6 minsLast updated:
Open Code Lab

Expected Interview Answer

A distributed transaction is a set of operations spanning multiple independent services or databases that must all succeed or all fail together, typically coordinated through protocols like two-phase commit or, more commonly at scale, through the Saga pattern of compensating actions.

Two-phase commit (2PC) has a coordinator ask every participant to prepare (lock resources and vote yes/no) in phase one, then, only if everyone voted yes, tell everyone to commit in phase two; this gives strong atomicity but blocks all participants resources while waiting on the slowest one, and if the coordinator crashes after phase one, participants can be stuck holding locks indefinitely. Because that blocking behavior is unacceptable for high-throughput, loosely coupled microservices, most modern systems instead use the Saga pattern: each service commits its own local transaction immediately and publishes an event, and if a later step fails, previously completed steps are undone by explicit compensating transactions (e.g., refund a payment that was already captured) rather than being rolled back atomically. Sagas trade strict ACID atomicity for availability and service autonomy, accepting that the system passes through temporarily inconsistent intermediate states that must be made eventually consistent and be safe to compensate. The choice between 2PC and Sagas comes down to whether you can tolerate blocking and tight coupling for strong atomicity, or need service independence and are willing to design idempotent, compensable steps.

  • Two-phase commit gives strong all-or-nothing atomicity across multiple resources
  • The Saga pattern preserves service autonomy and avoids the blocking failure modes of 2PC
  • Compensating transactions make partial-failure recovery explicit rather than implicit
  • Choosing the right pattern lets teams trade off consistency strength against availability and coupling

AI Mentor Explanation

A distributed transaction is like coordinating a multi-ground doubleheader where both matches must either both go ahead or both be called off together, never one played and the other cancelled. In the strict version, an official phones every ground to confirm pitch and weather readiness, waits for every yes, and only then gives the final go-ahead โ€” if one ground stalls, both matches sit blocked waiting. The looser, more common approach lets each ground start independently and, if one is rained out partway through, issues a formal reversal (refunded tickets, replayed innings) at the other ground instead of demanding perfect lockstep. That trade-off between blocking coordination and compensating after the fact is exactly the choice between two-phase commit and the Saga pattern.

Step-by-Step Explanation

  1. Step 1

    Choose atomicity strength

    Decide whether the workflow needs strict all-or-nothing atomicity (2PC) or can tolerate temporary inconsistency (Saga).

  2. Step 2

    Prepare or commit locally

    In 2PC, a coordinator asks all participants to prepare and vote; in a Saga, each service commits its own step immediately.

  3. Step 3

    Coordinate the outcome

    2PC commits everywhere only if all votes were yes; a Saga proceeds to the next step or triggers compensation on failure.

  4. Step 4

    Recover from failure

    2PC recovers by resolving pending votes (with risk of blocking); a Saga recovers by running compensating transactions for completed steps.

What Interviewer Expects

  • Explains two-phase commit and its blocking failure mode clearly
  • Explains the Saga pattern and compensating transactions as the common alternative at scale
  • Discusses the atomicity-vs-availability/coupling trade-off between the two approaches
  • Mentions idempotency requirements for retries and compensations to be safe

Common Mistakes

  • Assuming distributed transactions always mean two-phase commit
  • Not recognizing that 2PC blocks resources and has a coordinator single point of failure
  • Forgetting that Saga steps must be designed to be compensable and idempotent
  • Ignoring the intermediate, temporarily inconsistent states a Saga passes through

Best Answer (HR Friendly)

โ€œA distributed transaction is when several separate services need to complete an operation together as one unit, either all succeeding or all failing. One approach locks everything until every service confirms it can proceed, which is strong but can get stuck if one service is slow. The more common modern approach lets each service complete its own step right away and, if something later fails, undoes the earlier steps with a compensating action, trading some strictness for better reliability and independence between services.โ€

Code Example

Saga orchestrator with compensation on failure
async function placeOrderSaga(order) {
  const completed = []

  try {
    await paymentService.capture(order.paymentId)
    completed.push(() => paymentService.refund(order.paymentId))

    await inventoryService.reserve(order.items)
    completed.push(() => inventoryService.release(order.items))

    await shippingService.schedule(order.shippingId)
    completed.push(() => shippingService.cancel(order.shippingId))

    return { status: "confirmed" }
  } catch (err) {
    // run compensations in reverse order of completion
    for (const compensate of completed.reverse()) {
      await compensate()
    }
    return { status: "failed", reason: err.message }
  }
}

Follow-up Questions

  • What happens if the coordinator crashes between phase one and phase two of two-phase commit?
  • How does the Saga pattern differ between choreography and orchestration?
  • Why must Saga steps and compensations be idempotent?
  • How does three-phase commit attempt to reduce the blocking problem of 2PC?

MCQ Practice

1. What is the main downside of two-phase commit at scale?

All participants hold their locks/resources until the coordinator finishes both phases, which blocks throughput and creates a failure risk if the coordinator crashes.

2. What is a compensating transaction in the Saga pattern?

Because each Saga step commits independently, failure requires explicit compensating actions to undo prior committed steps.

3. What consistency trade-off does the Saga pattern accept compared to 2PC?

Sagas commit steps independently, so the system passes through intermediate states that are only eventually made consistent, unlike 2PC strict atomicity.

Flash Cards

What is a distributed transaction? โ€” A set of operations across multiple services/databases that must succeed or fail together.

Two-phase commit in one line? โ€” A coordinator asks all participants to prepare and vote, then commits everywhere only if all voted yes.

Saga pattern in one line? โ€” Each service commits locally immediately; failures are undone with compensating transactions instead of atomic rollback.

Main risk of 2PC? โ€” Participants can block indefinitely holding locks if the coordinator crashes mid-protocol.

1 / 4

Continue Learning