{"id":"saga-orchestration","name":"saga-orchestration","summary":"分散トランザクションやクロスアグリゲートワークフローのためのSagaパターンを実装します。","body":"# Saga Orchestration\n\nPatterns for managing distributed transactions and long-running business processes without two-phase commit.\n\n## Inputs and Outputs\n\n**What you provide:**\n- Service boundaries and ownership (which service owns which step)\n- Transaction requirements (which steps must be atomic, which can be eventual)\n- Failure modes for each step (transient vs. permanent, retry policy)\n- SLA requirements per step (informs timeout configuration)\n- Existing event/messaging infrastructure (Kafka, RabbitMQ, SQS, etc.)\n\n**What this skill produces:**\n- Saga definition with ordered steps, action commands, and compensation commands\n- Orchestrator or choreography implementation for your chosen pattern\n- Compensation logic for each participant service (idempotent, always-succeeds)\n- Step timeout configuration with per-step deadlines\n- Monitoring setup: state machine metrics, stuck saga detection, DLQ recovery\n\n---\n\n## When to Use This Skill\n\n- Coordinating multi-service transactions without distributed locks\n- Implementing compensating transactions for partial failures\n- Managing long-running business workflows (minutes to hours)\n- Handling failures in distributed systems where atomicity is required\n- Building order fulfillment, approval, or booking processes\n- Replacing fragile two-phase commit with async compensation\n\n---\n\n## Detailed section: Core Concepts\n\nMoved to `references/details.md`.\n\n## Detailed section: Templates\n\nMoved to `references/details.md`.\n\n## Best Practices\n\n### Do's\n\n- **Make every step idempotent** — Commands may be replayed on broker reconnect\n- **Design compensations carefully** — They are the most critical code path\n- **Use correlation IDs** — The `saga_id` must flow through every event and log\n- **Implement per-step timeouts** — Never wait indefinitely for a participant reply\n- **Log state transitions** — `saga_id`, `step_name`, `old_state → new_state` on every change\n- **Test compensation paths explicitly** — Inject failures at each step index in integration tests\n\n### Don'ts\n\n- **Don't assume instant completion** — Sagas are async and may take minutes\n- **Don't skip compensation testing** — The rollback path is the hardest to get right\n- **Don't couple services directly** — Use async messaging, never synchronous calls inside a saga step\n- **Don't ignore partial failures** — A step that partially executed still needs compensation\n- **Don't use a global timeout** — Each step has different latency characteristics\n\n---\n\n## Troubleshooting\n\n### Saga stuck in COMPENSATING state\n\nA saga enters compensation but never reaches FAILED. This means a compensation handler is throwing an unhandled exception and never publishing `SagaCompensationCompleted`. Add dead-letter queue (DLQ) handling to compensation consumers and ensure every compensation action publishes a result event even when the underlying operation was already rolled back.\n\n```python\nasync def handle_release_reservation(self, command: Dict):\n    try:\n        await self.release_reservation(command[\"original_result\"][\"reservation_id\"])\n    except ReservationNotFoundError:\n        pass  # Already released — treat as success\n    # Always publish completion, regardless of outcome\n    await self.event_publisher.publish(\"SagaCompensationCompleted\", {\n        \"saga_id\": command[\"saga_id\"],\n        \"step_name\": \"reserve_inventory\"\n    })\n```\n\n### Duplicate saga executions on restart\n\nIf your orchestrator service restarts mid-saga, it may replay events and re-execute already-completed steps. Guard every step action with an idempotency key — see **Template 3** above.\n\n### Choreography saga losing events\n\nIn a choreography-based saga, a downstream service may miss an event if it was offline when published. Use a durable message broker (Kafka with replication, RabbitMQ with persistence) and store the current saga state in a dedicated `saga_log` table so you can replay from the last known good step.\n\n### Timeout firing before a slow-but-valid step completes\n\nA step like `create_shipment` might take up to 15 minutes during peak load but your global timeout is 5 minutes, causing spurious compensation. Make step timeouts configurable per step type — see `references/advanced-patterns.md` for the `TimeoutSagaOrchestrator` implementation and the `STEP_TIMEOUTS` dict pattern.\n\n### Compensation order not matching execution order\n\nWhen two steps both complete before a failure is detected, compensation must run in strict reverse order or you leave data in an inconsistent state. Verify that `_compensate()` iterates from `current_step - 1` down to `0`, and add an integration test that deliberately fails at each step index to confirm correct rollback order.\n\n---\n\n## Advanced Patterns\n\nThe `references/` directory contains production-grade implementations not needed for most sagas:\n\n- **`references/advanced-patterns.md`** — Full `SagaOrchestrator` abstract base class, `TimeoutSagaOrchestrator` with per-step deadlines, detailed bank transfer compensating transaction chain, Prometheus instrumentation, stuck saga PromQL alerts, and DLQ recovery worker.\n\n---\n\n## Related Skills\n\n- `cqrs-implementation` — Pair sagas with CQRS for read-model updates after each step completes\n- `event-store-design` — Store saga events in an event store for full audit trail and replay capability\n- `workflow-orchestration-patterns` — Higher-level workflow engines (Temporal, Conductor) that build on saga concepts","author":"@wshobson","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/wshobson/agents/tree/main/plugins/backend-development/skills/saga-orchestration","license":"MIT","category":"document","lang":"en","tokens":1107,"stars":0,"calls30d":1,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[{"path":"references/advanced-patterns.md","size":15201,"sha256":"0134efa44616be80b4eff1576847a05a1e6742df69eb31446a4e2b5135375b34"},{"path":"references/details.md","size":10076,"sha256":"cbf86878798e444c22a8669bbd74d0d5344cf7d129dec9ce5bd21688b29a61ed"}],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":[]}}