Compensating Transaction
Reverse a real-world effect with a new action — original and compensation both remain
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
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.