ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

Compensating Action (Saga sub-pattern)

The operation that semantically cancels an already-committed step — the pattern that makes distributed rollback possible when XA is impossible. Cornerstone of Sagas (Garcia-Molina & Salem, 1987).

Problem

In a long EDI saga (PO → ASN → INVOIC → REMADV), step 5 may fail 3 days after step 1. No distributed system supports ACID transactional rollback across 3 days and 5 heterogeneous systems. Yet the already-committed work must be cleanly cancelled: reserved stock must be released, collected payment refunded, sent invoice contested by a credit note.

Forces

  • Classic ACID distributed transactions (XA) do not scale and lock resources for hours.
  • Local commit of a step is often technically irreversible (a sent INVOIC is received).
  • Semantic cancellation remains possible: a new action can be emitted to compensate the first's effect.
  • Not all actions are equally reversible: some (email send) irreversible, others (stock reservation) easily compensable.
  • Compensations must themselves be idempotent: on partial compensation failure, retrying must not amplify the damage.

Solution

For each positive step of the saga, explicitly define the corresponding compensating action. The saga orchestrator (or choreography) holds the list of executed steps and, on failure, executes compensations in reverse order. Compensations are themselves distributed steps that may fail and must be retried idempotently. "Non-compensable" actions (irreversible payment, shipment gone) must be minimised or placed at the saga's end: at worst they fall into a manual exception workflow.

Saga with compensations:

   Positive steps                 Compensations (on failure)
   ──────────────────             ─────────────────────────────────
   1. CreateOrder         ─────→   1bis. CancelOrder
   2. ReserveStock        ─────→   2bis. ReleaseStock
   3. ChargePayment       ─────→   3bis. RefundPayment
   4. ShipOrder           ─────→   4bis. RecallShipment (sometimes impossible)
   5. SendINVOIC          ─────→   5bis. SendCreditNote

   If step 3 fails:
   - execute 2bis (ReleaseStock)
   - execute 1bis (CancelOrder)
   - notify the customer

   If step 4 fails (very rare since shipment is after payment):
   - execute 4bis if possible
   - otherwise → manual exception workflow

   Note: compensations are NOT the exact inverse of the steps
   (no "Ctrl-Z"). They produce a new effect semantically
   equivalent to cancellation (e.g., CancelOrder = a new record in
   DB, not a delete).

EDI implementation

Concrete case: PO → ORDRSP → DESADV → INVOIC → REMADV saga. Step 4 (DESADV sent) then partner-side error: the partner answers with a categorical refusal APERAK. The saga triggers compensations: step 4bis = CancelDespatch (send cancellation DESADV), step 3bis = ReleaseShipment internally (cancel warehouse preparation), step 2bis = CancelInternalOrder (set order to Cancelled state). Step 1 (ORDERS received from partner) has no mandatory compensation: it's the initial event. Each compensation is coded as a Temporal activity or a Lambda in Step Functions, idempotent thanks to a Compensation Key. EDI tools: Camunda 8 natively models compensations (BPMN compensation boundary event), Temporal writes them as explicit activities. For a 1-month workflow between PO and REMADV, the list of possible compensations is typically recorded in a saga state document.

Anti-patterns

  • Forgotten compensation: a step without a corresponding compensation creates a saga rupture point.
  • Non-idempotent compensation: if it fails, retrying causes a double compensation (double refund credited).
  • Compensation that calls the symmetric positive step: CancelOrder calling DeleteOrder = audit loss. Always operate in append-only.
  • Disregarded compensation order: releasing stock before cancelling the order can create a transient incoherent state.
  • No compensation-failure handling: if compensation fails, an escalation flow to a human is needed — no point trying a compensation of compensation.
  • Compensation of a non-compensable action: some actions (irreversible payment) cannot be auto-compensated — explicit exception workflow to plan.

Sources

  • Garcia-Molina H., Salem K.Sagas, ACM SIGMOD 1987. The founding paper formalising Long Lived Transactions and their compensations. cornell.edu — Sagas (1987)
  • Richardson C.Microservices Patterns, Manning 2018. Chapter 4 on Sagas, their orchestrations and choreographies, their compensations.
  • Hohpe G., Woolf B.Enterprise Integration Patterns, Addison-Wesley 2003. Process Manager §312 (compensation transactions).
  • OMG BPMN 2.0 Specification. Compensation Boundary Event is a native BPMN construct to visually model compensations. omg.org — BPMN 2.0
  • Microsoft Cloud Design Patterns — Compensating Transaction. The Azure pattern card. learn.microsoft.com — compensating-transaction
  • Newman S.Building Microservices, O'Reilly 2015 (2nd ed. 2021). Chapter on distributed transactions and their alternatives.