qodebase logoqodebase
← qodebase

Unit 6 — coordinate payment, ledger, and webhooks without 2PC

Distributed Transactions & Sagas

A single payment touches three independent services: authorize the card (Unit 1), post the ledger entry (Unit 2), and emit the webhook (Unit 3). There is no shared database. If the ledger write fails after authorization succeeds, you cannot leave the customer charged with no record — and you cannot hold a global lock across three services while you figure it out.

This unit compares two-phase commit (why it blocks) with the saga pattern (how production systems actually coordinate), and builds a saga executor with compensating transactions.

Sub-unit 1 of 6

The product problem

Functional

  • Atomically update payment status, ledger, and downstream notifications across services.
  • On any step failure, roll back every previously committed step.
  • Make compensating actions idempotent (they will be retried).
  • Expose saga state for debugging and replay.

Non-functional

  • No partial state visible to external callers.
  • Consistent across process crashes and network partitions.
  • p99 saga completion under 500 ms on the happy path.
  • Compensation must complete even if the original step's effect is ambiguous.

Constraints

  • Each service owns its own database — no cross-service transactions.
  • Network calls fail transiently; steps must be retried.
  • A compensating transaction can itself fail and must be retried.
Finished reading? Mark this sub-unit complete to unlock the next.