Implementing Saga Patterns

1. Saga Orchestration Pattern

AspectDetail
DefinitionCentral orchestrator drives steps; tells each service what to do
StateHeld by orchestrator (durable workflow state)
ProsVisible flow; easier debugging; explicit compensation
ConsOrchestrator can become god-service if logic creeps in
ToolsCamunda, Temporal, AWS Step Functions, Axon

Example: Order Saga Orchestrator (Temporal-style)

public class OrderSaga {
    public void run(OrderRequest req) {
        try {
            payment.charge(req);
            inventory.reserve(req);
            shipping.schedule(req);
            order.markConfirmed(req.orderId());
        } catch (Exception ex) {
            shipping.cancel(req.orderId());
            inventory.release(req.orderId());
            payment.refund(req.orderId());
            order.markFailed(req.orderId(), ex.getMessage());
        }
    }
}

2. Saga Choreography Pattern

AspectDetail
DefinitionEach service reacts to events; no central coordinator
FlowEmerges from event subscriptions
ProsLoose coupling; easy to add reactors
ConsHard to see end-to-end; cyclic dependencies risk

Choreography Flow

OrderPlaced → Payment reacts → PaymentCharged → Inventory reacts → InventoryReserved → Shipping reacts → Shipped
                                       ↓ (fail)
                              PaymentFailed → Order reacts → OrderCancelled
        

3. Implementing Compensating Transactions

PropertyRequirement
Semantically ReversesUndoes business effect (refund instead of "delete payment")
IdempotentMust be safe to retry
Best EffortMay not perfectly restore state (e.g., email already sent)
LoggedAudit trail of compensation
Forward ActionCompensation
Charge paymentRefund payment
Reserve inventoryRelease reservation
Send emailSend "ignore previous" email
Schedule shipmentCancel shipment

4. Managing Saga State Machines

StateDescription
STARTEDSaga initiated
PAYMENT_CHARGEDPayment step done
INVENTORY_RESERVEDStock reserved
SHIPPEDItem dispatched
COMPLETEDSaga succeeded
COMPENSATINGRolling back
FAILEDCompensated; saga ended in failure

5. Handling Saga Failures

Failure TypeHandling
TransientRetry with backoff; don't compensate yet
Business RuleCompensate prior steps; mark FAILED
Permanent (4xx)No retry; immediate compensation
Compensation FailureAlert + manual intervention queue

6. Saga Timeout Pattern

AspectDetail
Per-Step TimeoutCap each activity (e.g., 30s)
Saga-Wide TimeoutTotal deadline (e.g., 24h for order)
ActionTrigger compensation on timeout
ToolsTemporal timers, Camunda BPMN timers

7. Saga Recovery Pattern

TriggerRecovery
Orchestrator CrashResume from last persisted state
Service DownRetry with exponential backoff
Stuck SagaOperator console: retry / abort / skip step
Data LossReplay from saga event log

8. Saga Isolation Pattern

CountermeasureDetail
Semantic LockMark record as "in-saga" (e.g., status=PENDING) to block other ops
Commutative UpdatesOrder-independent ops (additive)
Pessimistic ViewHide partially-committed state from queries
Re-read ValueVerify assumptions before each step
Version FileTrack concurrent updates
Warning: Sagas are NOT ACID — they have no isolation by default. Lack of isolation can show partial state to other transactions.

9. Saga Logging Pattern

Logged ItemPurpose
Saga ID + Correlation IDTrace across services
Step Started/CompletedForensics, dashboards
Compensation AttemptsAudit, debugging
Final OutcomeSLA reporting

10. Saga Compensation Order Pattern

RuleDetail
LIFO OrderCompensate in reverse of forward steps
Skip Untaken StepsOnly compensate steps that succeeded
Persistent PlanCompensation plan stored before forward execution
Continue on Compensation FailTry all compensations; flag failures separately