Architecture decisions

Saga compensation: define the state you can reach

Saga compensation creates a new business outcome after local commits. It cannot promise that every participant returns to its original state. A proposed booking recovery matrix makes payment uncertainty, owned resources and irreversible effects explicit before implementation.

Design artifact
5 recovery states and 5 proposed failure drills
Core distinction
Confirmed compensation differs from a requested or uncertain action
Boundary
Fictional workflow; no payment or reservation provider invoked
A workflow takes a separate recovery route after a later stage becomes blocked.
Conceptual illustration of reaching an accepted alternative state after partial workflow completion.

Start with the state the business can accept

A saga compensation is a new business action that addresses an earlier committed action. It is not a promise to restore every participating system to its original state. The architecture needs to name the state it can reach after failure, including any external effects that remain visible.

Consider a proposed booking workflow: reserve capacity, capture a payment and issue a confirmation. If confirmation fails after the first two steps commit, deleting the local booking row does not release external capacity or reverse the payment. Conversely, refunding a payment cannot make the original charge disappear from an external provider's history.

This article supplies a proposed recovery matrix and workflow decision record. They are design artifacts for a fictional workflow. No payment, reservation or compensation provider was invoked. Their purpose is to make recovery obligations reviewable before the happy-path implementation hides them.

Draw the commit boundaries before drawing the arrows

Each participant commits locally. The coordinator may know that a request was sent without knowing whether the participant committed it. A timeout therefore creates uncertainty, not automatic evidence that nothing happened. The next action may be to query the participant by a stable operation identifier rather than submit an opposite action immediately.

The proposed workflow records a reservation identifier, payment operation identifier and confirmation outcome under one saga identifier. Each step also has a durable status that distinguishes requested, confirmed, uncertain and failed. These labels are a proposed vocabulary, not a universal saga protocol. Their usefulness depends on participants exposing enough evidence to resolve uncertain outcomes.

Reservation, payment and customer confirmation each have their own committed or uncertain outcome.
Figure 1. Proposed boundaries for the fictional booking: each participant supplies its own outcome evidence. A coordinator timeout does not prove that a participant did nothing. View full-size figure.

Microsoft's saga pattern guidance describes sequences of local transactions with compensating or continuing actions after failure. The separate compensating-transaction guidance explains that compensation is business-specific and may not restore the original state, especially when concurrent work has changed it.

A durable outbox can help publish a local state change and its outgoing message consistently. It does not supply the business meaning of undoing a payment or releasing a reservation. The outbox crash-case article tests that local publication boundary; this design begins where independent participants have already made their own commitments.

Define compensation against the owned resource

Suppose the workflow reserved one capacity allocation. Its compensation should release that identified allocation if release remains valid. It should not write an old total-capacity value back over the current value. Other bookings may have arrived since the original reservation, and a snapshot overwrite would erase their legitimate changes.

The same principle applies to payment recovery. Refer to the original provider operation and use its supported refund or cancellation contract. Distinguish a requested refund from a confirmed one. The design must account for rejection, delayed confirmation and an uncertain network response without claiming a fictional payment rule applies to every provider.

Proposed recovery actions and participant evidence
Committed or uncertain stepProposed recovery actionEvidence needed for completion
Reservation confirmedRelease its specific allocationParticipant confirms that allocation is released
Payment capturedRequest supported compensation for that operationProvider confirms the resulting payment state
Payment response uncertainResolve the original operation firstStable operation lookup establishes its outcome
Confirmation already deliveredCorrect the customer-visible statusProduct-defined communication and support outcome
Compensation repeatedly unresolvedEnter an owned manual-review stateNamed owner accepts the case with its evidence

The table deliberately avoids a generic "rolled back" terminal label. Released capacity, a confirmed refund and a corrected customer message are different observations. A system can complete one while another remains unresolved. Record the partial state rather than hiding it behind one success flag.

Compensation order should follow dependencies and business risk. It need not be the exact reverse of the forward call order. For example, releasing capacity before resolving whether a booking can still be fulfilled may violate a product decision. The matrix asks the team to decide that relationship instead of treating a reversed arrow as a specification.

Make recovery resumable when the recovery itself fails

A compensation call can time out after it commits, just like a forward call. Give each recovery operation a stable identity and define repeat behavior at the participant boundary. Retrying a refund with a new operation identity is not equivalent to retrying the same intended refund.

The coordinator's journal should persist the intended action before dispatch where the chosen storage and messaging design supports that sequence, then record evidence of the result. After a restart, it needs to distinguish an action that was never sent from one whose outcome is unknown. A local retry counter alone cannot resolve that distinction.

A durable recovery intention leads to a participant action whose confirmed or uncertain outcome determines the next step.
Figure 2. Proposed recovery journal: persist identity and intended action, resolve participant outcome, then complete or escalate with the remaining obligation visible. View full-size figure.

The proposed failure drill sheet contains five cases: uncertain forward payment, lost compensation response, coordinator restart, concurrent resource change and an irreversible customer-visible effect. Every outcome cell is pending. Running those cases against the actual participants is the work required to turn the design into evidence.

Use bounded retries and an escalation policy when an outcome cannot be resolved automatically. A manual-review state needs ownership, the relevant operation identifiers and a clear list of actions already attempted. It is not a garbage bin labeled "retry later." Avoid including unnecessary customer payloads in a diagnostic packet; the audit-log design article separates useful event evidence from excessive data retention.

Reserve the word complete for a defined outcome

A workflow can finish successfully, recover to an accepted alternative or remain unresolved. Those states have different product meanings. If the booking cannot be fulfilled but its capacity is released and payment compensation is confirmed, the product may call the outcome canceled. If the payment state is still uncertain, that same label could mislead the customer.

The decision record therefore asks for an invariant and evidence at each terminal state. "Canceled" might require no active allocation and a confirmed supported payment outcome. "Manual review" might require a named owner and visible unresolved obligations. These are example criteria to adapt, not claims that every booking business uses the same contract.

There is also a point after which forward recovery is preferable to compensation. If a physical service has already been delivered, reversing an earlier database flag may be meaningless. The workflow needs an explicit decision about what remains compensable and who handles the remaining obligation. Place that decision near the irreversible action in the design.

Review the recovery matrix alongside the normal workflow before implementation. If a participant cannot identify an earlier operation or expose its outcome, record the resulting uncertainty as an architectural constraint. The useful guarantee is the business state the system can demonstrate, including what it cannot automatically repair.

Sources

Documentation checked .

  1. Microsoft: Compensating Transaction pattern
  2. Microsoft: Saga distributed transactions

Continue the conversation

Comments (7)

  1. Dreamtsoft Editorial

    Releasing the identified allocation makes the concurrent-booking case concrete. Restoring an old capacity total would overwrite work that belongs to another booking.

  2. Dreamtsoft Editorial

    An uncertain payment response needs an operation lookup before choosing a recovery action. The timeout alone cannot establish whether the forward operation committed.

  3. Dreamtsoft Editorial

    The customer-facing cancellation label needs the same evidence as the internal terminal state. An unresolved payment should remain visible to whoever owns the case.

  4. Dreamtsoft Editorial

    A lost compensation response is worth testing independently from a failed forward call. The recovery operation needs repeat behavior that preserves its original identity.

  5. Dreamtsoft Editorial

    Manual review becomes actionable when it records an owner and the unresolved obligation. A generic retry status gives the next operator little basis for deciding what is safe.

  6. Dreamtsoft Editorial

    The already-delivered confirmation exposes a limit of compensation. A later database change cannot retract what the customer has read, so communication has its own completion criterion.

  7. Dreamtsoft Editorial

    The proposed matrix leaves provider outcomes pending. Filling those cells requires evidence from the actual participants before the workflow can promise an accepted recovery state.

Leave a comment

Your name and comment stay in this page and are cleared after the spam check.

10–2,000 characters. Keep the discussion relevant to this article.

Spam protection verification
Spam protection loads when you begin the form.

JavaScript is required to use this form and its spam protection.