# Saga Pattern

> The saga pattern as a runnable model: a long-running transaction that runs compensating steps to roll back on failure, checked so a completed saga committed every step and a rolled-back one undid its work.

Canonical: https://fizzbee.io/design/patterns/saga-pattern/
Source: https://github.com/fizzbee-io/fizzbee/tree/main/examples/references/13-02-02-saga-pattern


Long-running transaction with compensation

**Demonstrates:** saga pattern, compensating transactions, rollback

```fizz
# Example 0073: Saga Pattern
# Long-running transaction with compensation
# Demonstrates: saga pattern, compensating transactions, rollback

State = enum('INIT', 'STEP1_DONE', 'STEP2_DONE', 'COMPLETED', 'COMPENSATING', 'ROLLED_BACK')

action Init:
    saga_state = State.INIT
    step1_committed = False
    step2_committed = False

atomic action ExecuteStep1:
    require saga_state == State.INIT

    step1_committed = True
    saga_state = State.STEP1_DONE

atomic action ExecuteStep2:
    require saga_state == State.STEP1_DONE

    # Step 2 can fail
    oneof:
        # Success path (atomic together)
        atomic:
            step2_committed = True
            saga_state = State.STEP2_DONE

        # Failure path - trigger compensation
        saga_state = State.COMPENSATING

atomic action Complete:
    require saga_state == State.STEP2_DONE

    saga_state = State.COMPLETED

atomic action CompensateStep1:
    require saga_state == State.COMPENSATING

    # Rollback step 1
    step1_committed = False
    saga_state = State.ROLLED_BACK

# Safety: if completed, both steps committed
always assertion CompletionInvariant:
    if saga_state == State.COMPLETED:
        return step1_committed and step2_committed
    return True

# Safety: if rolled back, step1 compensated
always assertion CompensationInvariant:
    if saga_state == State.ROLLED_BACK:
        return not step1_committed
    return True

atomic action NoOp:
    if saga_state == State.COMPLETED or saga_state == State.ROLLED_BACK:
        pass
```
Run it in the FizzBee playground: https://fizzbee.io/play


**Expected result** (from `fizz`):

```
StateSpaceOptions: options:{max_actions:100 max_concurrent_actions:2}
Nodes: 7, queued: 0
Valid Nodes: 7 Unique states: 6
IsLive: true
PASSED: Model checker completed successfully
```

[Source on GitHub](https://github.com/fizzbee-io/fizzbee/tree/main/examples/references/13-02-02-saga-pattern)

## Language features used

[Assertions](/reference/language/assertions/), [Flow Modifiers](/reference/language/flow-modifiers/), [Data Structures](/reference/language/data-structures/)

