← PATTERNS

Compensating Transaction

Reverse a real-world effect with a new action — original and compensation both remain

Core principle

When a committed action produced an irreversible real-world effect, compensate with a new L0 event — never delete or rewrite the original.

A compensating transaction undoes consequences, not history. The charge happened; the refund happened; both are permanent facts with full accountability. Net effect may be zero; the log is richer, not sanitized.

The pattern

PaymentRefunded {
  originalChargeId,
  amount,
  refundReason,
  authorisedBy,
  refundedAt
}

Use when a committed action moved money, shipped goods, dispensed medication, or deployed software — and the effect must be reversed operationally. Distinguish from supersession (judgment change) and correction event (recording error).

Sagas across bounded contexts compose compensating steps; each step remains an observable L0 fact. Full treatment: When Facts Are Wrong.

In software systems

Correct implementation: refunds, returns, rollbacks, and revocations are domain events referencing originals — not row deletion or status overwrite.

What good looks like: reconciliation matches charge and refund pairs; audit shows both legs.

In human organisations

Correct implementation: order cancellations after fulfilment trigger return/refund processes recorded as committed acts — not erasure from the order book.

What good looks like: finance, legal, and operations share one append-only story of what happened and what was undone.

In socio-technical systems

Correct implementation: deployment rollbacks emit compensating events; regulators see charge and reversal, not a ledger that never showed the mistake.

What good looks like: mutable history is architecturally impossible because correction always adds facts.

Why this solves the anti-pattern

CRUD as domain language

Treating persistence as current-state storage invites “delete the bad row.” Compensating transactions preserve causal chains — essential for immutability of facts in regulated domains.