# Compensation is a business action, not a database undo

A distributed workflow cannot usually erase every completed step. Define the corrective business action for each effect and make unresolved states visible.

By Cobnex editorial. Published 2026-09-10. Updated 2026-09-11.

## Some effects have already left the database

A fulfilment workflow reserves stock, authorises a payment and books a carrier. The carrier booking fails after the first two steps succeeded. A local database rollback cannot release a reservation held by another service or change the payment provider's state.

A saga coordinates such steps through local transactions and explicit recovery actions. Compensation is the action that moves the business towards an acceptable state after part of the workflow has completed. It may release stock or request reversal of an authorisation, but it is not a time machine that makes the earlier work disappear.

Choose the business outcome first. The right recovery may be to retry the carrier, use another approved service or cancel the order. These choices depend on policy and the effects already committed.

## Map effects and available corrections

For every step, record what becomes durable, how success is identified and which correction is possible. Include the period during which that correction remains valid.

A carrier booking might be cancellable before collection and require a different process afterwards. A notification already sent cannot be unsent, even if a follow-up can correct its message. Treat these limits explicitly rather than assigning every step a function called undo.

### A failed booking leaves earlier effects to resolve

The coordinator records each outcome and chooses a business recovery path based on what actually committed.

1. **Reserve stock**: Record reservation identity and release operation
2. **Authorise payment**: Record provider operation and reversal options
3. **Book carrier**: On failure, distinguish rejection from uncertainty
4. **Recover**: Retry, compensate or escalate under current business rules

The diagram shows one possible sequence. Compensation order should follow dependencies and business constraints, not an assumption that reversing the list is always correct.

## Preserve uncertainty before compensating

A timeout at the carrier does not prove the booking failed. The service may have accepted it while the response was lost. Reconcile the operation identifier before releasing stock or changing payment state based on an assumed failure.

Give forward and compensating operations stable identities so retries do not multiply effects. Record their outcomes durably. Compensation can fail too, leaving a partially recovered workflow that needs another attempt or human resolution.

Do not mark the saga complete merely because every recovery command was submitted. Verify the required business state through the service contracts available.

## Handle concurrent changes carefully

Other work may occur while the saga is running. A compensation that blindly restores an old database snapshot can overwrite legitimate later changes. Prefer a business operation scoped to the effect being corrected, such as releasing a particular reservation.

Use version checks or other concurrency rules where necessary. The correction should preserve current authority and state constraints, including cases where the original requester no longer has permission to initiate new work.

## Make the incomplete state operable

Keep a durable record of completed steps, uncertain operations and compensation attempts. Give operators a supported route to inspect and resolve the remaining business issue.

Test both the forward failure and a failed compensation. Include an irreversible effect so the team must demonstrate the manual or forward-recovery path. A saga is dependable when partial completion is an explicit state with a known owner, rather than an exception that disappears into a retry loop.

## Sources

- [Microsoft Learn: compensating transactions](https://learn.microsoft.com/en-us/azure/architecture/patterns/compensating-transaction)
- [AWS Builders' Library: idempotent APIs](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/)
