UNDO · COMPENSATING TRANSITIONS

Undo state: append a compensating transition

Undo the last steps of an order that reserved stock, charged a card and sent an email, and compare deleting history with appending its reversal.

Computed experiment · sixty inspection seconds

Your experiment

An order agent recorded five actions: add a kettle, reserve its stock, add a filter, charge 120 and send a confirmation email. The user asks to undo the last three. The opening agent deletes those events from the session log. Compare what the session, the payment provider and the customer’s inbox each believe, then switch to compensation and break it with a crash.

Play replays the computed run over sixty inspection seconds; Next event steps, Restart rewinds, and Inspection time scrubs. Any input change recomputes the run and rewinds it without autoplay.

Event trace

    Computed data

    Final metrics

    Deterministic fixture: the inventory, payment and email systems commit the moment they are called; a crash strikes after the refund succeeds and before its event is appended; the retry calls refund again. Compensations run newest first, as in the linked article. No real service is called.

    Three places the order lives

    An order exists in the session log and state, in the inventory system, at the payment provider and in the customer’s inbox. Undo strategy decides how “undo” is done: delete the events, restore a state snapshot from before them, or append a compensating event for each action, newest first. Actions to undo picks how many of the five recorded actions to reverse. Crash after the refund, before its event and Idempotency key on the refund test a compensation that is interrupted and retried. Kettle already shipped makes the reservation impossible to release.

    The opening run: the session forgets, the world does not

    Deleting A3 to A5 makes the session look clean: the cart holds only the kettle and the log replays to that state. But the payment provider still holds a 120 charge, the customer still holds a confirmation email, and the log no longer shows that either ever happened, so nobody can explain the charge. Three problems: net charge 120 instead of 0, history erased, confirmation uncorrected. Undo 1 action: the charge is right, but the email stays uncorrected and its event is erased; undo all 5 and the stock stays reserved as well.

    Snapshot versus compensation

    Restore an earlier state snapshot keeps all five events, so the log now replays to a cart with a filter and a 120 charge while the state says otherwise: log and state disagree, and the charge still stands. Append compensating events adds a correction email, a refund of 120 and a removal of the filter. Net charge is 0, the log has 8 events and replays to the stored state, and the history shows both the action and its reversal. An email cannot be unsent, so its compensation is a correction.

    Failure boundary: the retried compensation

    With compensation, tick Crash after the refund, before its event: the refund succeeded, but its event was never appended, so the retry refunds again and the net charge becomes -120. Tick Idempotency key on the refund: the provider returns the first refund and the net is 0. With compensation and 4 actions to undo, the reservation is released; tick Kettle already shipped and it cannot be, so the compensation opens a return instead. Compensation is the only strategy that keeps every system consistent, and only if each compensating call is idempotent.

    Reading the run and its limits

    Play replays the five recorded actions, the undo, the external check and the outcome over sixty inspection seconds; the table lists each undo action and its external effect. Next event, Restart, Speed and Inspection time control the replay. Real compensations can fail or need a person, and some effects have no inverse at all; production designs keep a durable intent record so a crash between a side effect and its event can be detected rather than guessed.

    Views are my own and do not represent any employer, past or present.

    Search