Distributed Systems TheoryExpert16 min read2 questions

Distributed Transactions, Sagas and Exactly-Once

What to do when one operation must span two systems. Why 2PC is usually the wrong answer, how sagas work, and why exactly-once delivery is impossible but exactly-once processing is not.

Covers: Two-phase commit, sagas and compensation, the outbox pattern, delivery semantics, deduplication, exactly-once processing

A single database transaction is easy. The moment an operation must touch two databases, or a database and a payment provider, or a database and a message broker, atomicity stops being free and becomes a design problem with several unsatisfying answers.

Filter
0/2 mastered
Expertsaga2pctransactionsAsked at Amazon, Uber

30-second answer

Two-phase commit gives real atomicity but requires every participant to hold locks until the coordinator decides, and if the coordinator dies mid-decision the participants block indefinitely - unacceptable across services and impossible with an external payment provider. The practical answer is a saga: a sequence of local transactions, each with a compensating action, coordinated either by choreography through events or by an orchestrator. You give up isolation and accept that intermediate states are visible, in exchange for availability and no distributed locks.

Expertexactly-onceidempotencymessagingAsked at Confluent, Stripe

30-second answer

Exactly-once delivery is impossible over an unreliable network - the sender can never distinguish a lost message from a lost acknowledgement, so it must either risk losing it or risk sending it twice. What is achievable is exactly-once processing: at-least-once delivery combined with idempotent consumers that deduplicate by message ID, plus atomic commit of the side effect and the dedup record. The transactional outbox pattern extends this to publishing, writing the message into the same database transaction as the state change so you cannot commit one without the other.

Showing 2 of 2 questions for distributed-transactions-and-idempotency.

Check your understanding

4 questions · no sign-up, nothing stored

0/4 answered
Question 1

1.Why is two-phase commit usually unsuitable across microservices?

Question 2

2.What does a saga give up compared to a distributed transaction?

Question 3

3.What problem does the transactional outbox pattern solve?

Question 4

4.A consumer applies a side effect, then records the message ID in a second transaction. What is wrong?

Hands-on challenge

Build it - this is what you talk about in a deep-dive round.

Implement an order saga with compensation

Build a three-step saga (reserve inventory → charge payment → create shipment) that is correct under crashes and duplicate messages.

Requirements

  • Implement an orchestrator that persists saga state after every transition and resumes correctly after its own crash.
  • Write a compensation for each forward step and make every one idempotent.
  • Use the transactional outbox so no event is published for an uncommitted change.
  • Make each consumer idempotent with a dedup record committed alongside the side effect.
  • Test by killing the orchestrator between every pair of steps and verifying no partial state survives.

Stretch goals

  • Add a semantic lock so concurrent orders cannot double-reserve the last item.
  • Handle a compensation that fails permanently, including the operator-facing surface for it.