本文へ移動
cccskills
無料GitHub で公開

acc-saga-pattern-knowledge

Saga Pattern knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for saga orchestration, choreography, and distributed transaction audits.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md13.1 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Saga Pattern Knowledge Base

Quick reference for Saga pattern and PHP implementation guidelines for distributed transactions.

Core Principles

Saga Pattern Overview

┌─────────────────────────────────────────────────────────────────────────┐
│                         SAGA PATTERN                                     │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│   CHOREOGRAPHY (Event-driven)                                            │
│   ┌─────────┐    event    ┌─────────┐    event    ┌─────────┐           │
│   │ Service │───────────▶ │ Service │───────────▶ │ Service │           │
│   │    A    │             │    B    │             │    C    │           │
│   └─────────┘             └─────────┘             └─────────┘           │
│        │                       │                       │                │
│        └───────── compensate ──┴─── compensate ────────┘                │
│                                                                          │
│   ORCHESTRATION (Central coordinator)                                    │
│                    ┌───────────────┐                                    │
│                    │  Saga         │                                    │
│                    │  Orchestrator │                                    │
│                    └───────┬───────┘                                    │
│              ┌─────────────┼─────────────┐                              │
│              ▼             ▼             ▼                              │
│        ┌─────────┐   ┌─────────┐   ┌─────────┐                          │
│        │ Service │   │ Service │   │ Service │                          │
│        │    A    │   │    B    │   │    C    │                          │
│        └─────────┘   └─────────┘   └─────────┘                          │
│                                                                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│   Saga = Sequence of local transactions + compensating actions           │
│                                                                          │
│   T1 → T2 → T3 → ... → Tn                                               │
│    ↓    ↓    ↓          ↓                                               │
│   C1   C2   C3        Cn                                                │
│                                                                          │
│   If Ti fails: execute Ci-1, Ci-2, ..., C1 (reverse order)              │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Key Concepts

ConceptDescription
SagaSequence of local transactions with compensations
StepSingle local transaction within saga
Compensating ActionUndoes the effect of a previous step
OrchestratorCentral coordinator managing saga execution
ChoreographyDecentralized, event-driven saga coordination
Saga StateCurrent execution status (enum)
IdempotencySteps can be retried safely
Semantic LockPrevents concurrent saga conflicts

Choreography vs Orchestration

AspectChoreographyOrchestration
CoordinationDecentralized (events)Centralized (orchestrator)
CouplingLooseTighter to orchestrator
VisibilityDistributed (hard to trace)Centralized (easy to monitor)
ComplexitySimpler servicesSimpler overall flow
TestingHarder (distributed)Easier (centralized logic)
Best forSimple sagas (2-3 steps)Complex sagas (4+ steps)

Quick Checklists

Saga Design Checklist

  • Each step is a local transaction
  • Every step has compensating action
  • Compensations are idempotent
  • Forward actions are idempotent
  • Saga state is persisted
  • Failure handling defined for each step
  • Timeout handling for long-running steps

Orchestrator Checklist

  • State machine for saga lifecycle
  • Persistent saga state storage
  • Step execution tracking
  • Compensation ordering (reverse)
  • Retry logic with limits
  • Dead letter for failed sagas
  • Correlation ID propagation

Compensation Checklist

  • Semantic undo (not rollback)
  • Handles partial completion
  • Idempotent (can run multiple times)
  • Doesn't fail silently
  • Logs compensation actions
  • Eventual consistency acceptable

PHP 8.5 Saga Patterns

Saga State Enum

<?php

declare(strict_types=1);

namespace Domain\Shared\Saga;

enum SagaState: string
{
    case Pending = 'pending';
    case Running = 'running';
    case Compensating = 'compensating';
    case Completed = 'completed';
    case Failed = 'failed';
    case CompensationFailed = 'compensation_failed';

    public function canTransitionTo(self $next): bool
    {
        return match ($this) {
            self::Pending => $next === self::Running,
            self::Running => in_array($next, [self::Completed, self::Compensating], true),
            self::Compensating => in_array($next, [self::Failed, self::CompensationFailed], true),
            self::Completed, self::Failed, self::CompensationFailed => false,
        };
    }

    public function isTerminal(): bool
    {
        return in_array($this, [self::Completed, self::Failed, self::CompensationFailed], true);
    }
}

Saga Step Interface

<?php

declare(strict_types=1);

namespace Domain\Shared\Saga;

interface SagaStepInterface
{
    public function name(): string;

    public function execute(SagaContext $context): StepResult;

    public function compensate(SagaContext $context): StepResult;

    public function isIdempotent(): bool;
}

Saga Context

<?php

declare(strict_types=1);

namespace Domain\Shared\Saga;

final class SagaContext
{
    /** @var array<string, mixed> */
    private array $data = [];

    public function __construct(
        public readonly string $sagaId,
        public readonly string $correlationId,
        public readonly \DateTimeImmutable $startedAt
    ) {}

    public function set(string $key, mixed $value): void
    {
        $this->data[$key] = $value;
    }

    public function get(string $key, mixed $default = null): mixed
    {
        return $this->data[$key] ?? $default;
    }

    public function has(string $key): bool
    {
        return array_key_exists($key, $this->data);
    }

    public function all(): array
    {
        return $this->data;
    }
}

Saga Orchestrator

<?php

declare(strict_types=1);

namespace Application\Shared\Saga;

use Domain\Shared\Saga\SagaContext;
use Domain\Shared\Saga\SagaState;
use Domain\Shared\Saga\SagaStepInterface;
use Domain\Shared\Saga\StepResult;

final class SagaOrchestrator
{
    /** @var array<SagaStepInterface> */
    private array $steps = [];

    /** @var array<string> */
    private array $completedSteps = [];

    private SagaState $state = SagaState::Pending;

    public function __construct(
        private readonly SagaContext $context,
        private readonly SagaPersistenceInterface $persistence
    ) {}

    public function addStep(SagaStepInterface $step): self
    {
        $this->steps[] = $step;
        return $this;
    }

    public function execute(): SagaResult
    {
        $this->state = SagaState::Running;
        $this->persistence->save($this->context->sagaId, $this->state, []);

        foreach ($this->steps as $step) {
            $result = $step->execute($this->context);

            if ($result->isFailure()) {
                return $this->compensate($step->name(), $result->error());
            }

            $this->completedSteps[] = $step->name();
            $this->persistence->save(
                $this->context->sagaId,
                $this->state,
                $this->completedSteps
            );
        }

        $this->state = SagaState::Completed;
        $this->persistence->save($this->context->sagaId, $this->state, $this->completedSteps);

        return SagaResult::completed($this->context);
    }

    private function compensate(string $failedStep, string $error): SagaResult
    {
        $this->state = SagaState::Compensating;
        $this->persistence->save($this->context->sagaId, $this->state, $this->completedSteps);

        $stepsToCompensate = array_reverse($this->completedSteps);

        foreach ($stepsToCompensate as $stepName) {
            $step = $this->findStep($stepName);
            $result = $step->compensate($this->context);

            if ($result->isFailure()) {
                $this->state = SagaState::CompensationFailed;
                $this->persistence->save($this->context->sagaId, $this->state, $this->completedSteps);

                return SagaResult::compensationFailed($this->context, $error, $result->error());
            }
        }

        $this->state = SagaState::Failed;
        $this->persistence->save($this->context->sagaId, $this->state, $this->completedSteps);

        return SagaResult::failed($this->context, $error);
    }

    private function findStep(string $name): SagaStepInterface
    {
        foreach ($this->steps as $step) {
            if ($step->name() === $name) {
                return $step;
            }
        }
        throw new \RuntimeException("Step not found: {$name}");
    }
}

Common Violations Quick Reference

ViolationWhere to LookSeverity
Missing compensationSaga step without compensate()Critical
Non-idempotent stepsRetry causes duplicate effectsCritical
No saga state persistenceState lost on crashCritical
Synchronous distributed txTwo-phase commit attemptCritical
Forward-only sagaNo compensation at allWarning
Missing correlation IDCan't trace saga executionWarning
No timeout handlingSaga hangs foreverWarning
Compensation order wrongNot reversedWarning

Detection Patterns

# Find saga implementations
Glob: **/Saga/**/*.php
Glob: **/*Saga.php
Grep: "SagaStep|SagaOrchestrator|Saga.*Interface" --glob "**/*.php"

# Check for saga state management
Grep: "SagaState|saga_state|enum.*Saga" --glob "**/*.php"

# Find compensating actions
Grep: "compensate|compensation|rollback.*step" --glob "**/Saga/**/*.php"

# Detect missing compensations
Grep: "implements.*SagaStep" --glob "**/*.php"
# Then check each for compensate() method

# Find choreography events
Grep: "SagaEvent|SagaCompleted|SagaFailed" --glob "**/Event/**/*.php"

# Check for saga persistence
Grep: "SagaPersistence|SagaRepository|saga.*save" --glob "**/*.php"

# Find potential issues
Grep: "Transaction.*begin.*Transaction" --glob "**/*.php"  # Distributed tx attempt

Example: Order Saga

Order Saga: Reserve Inventory → Charge Payment → Ship Order

Step 1: Reserve Inventory
  - Action: Decrement stock
  - Compensation: Release stock (increment)

Step 2: Charge Payment
  - Action: Charge credit card
  - Compensation: Refund charge

Step 3: Ship Order
  - Action: Create shipment
  - Compensation: Cancel shipment

If Step 2 fails:
  1. Compensate Step 1 (release inventory)
  2. Mark saga as Failed

References

For detailed information, load these reference files:

  • references/saga-patterns.md — Choreography and orchestration patterns
  • references/compensation.md — Compensating transaction strategies
  • references/antipatterns.md — Common violations with detection patterns
  • references/php-specific.md — PHP 8.5 specific implementations

Assets

  • assets/report-template.md — Structured audit report template

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Master backend architectures, REST API design, microservices, and server-side development across multiple languages. Use this as a central index to access specialized sub-skills.

日本語の概要は準備中です。原文の説明を表示しています。

MikeCheng1208/BattleTree22026年7月22日 更新

在每次回复中使用固定前缀并列出本次实际参考的指令/文件,便于校验是否遵循上下文与规则。

日本語の概要は準備中です。原文の説明を表示しています。

MikeCheng1208/BattleTree22026年7月22日 更新

Automate 21risk tasks via Rube MCP (Composio). Always search tools first for current schemas.

日本語の概要は準備中です。原文の説明を表示しています。

MikeCheng1208/BattleTree22026年7月22日 更新

Automate 2chat tasks via Rube MCP (Composio). Always search tools first for current schemas.

日本語の概要は準備中です。原文の説明を表示しています。

MikeCheng1208/BattleTree22026年7月22日 更新

Arquitecto de Soluciones Principal y Consultor Tecnológico de Andru.ia. Diagnostica y traza la hoja de ruta óptima para proyectos de IA en español.

日本語の概要は準備中です。原文の説明を表示しています。

MikeCheng1208/BattleTree22026年7月22日 更新

[00] META. Orchestrate skills into dynamic chains for complex tasks. Analyzes the task, discovers available skills, builds an optimal chain, explains why each skill is needed, and executes step-by-step with user confirmation. Use for any complex task requiring multiple thinking/research/analysis steps. Triggers on "plan this", "how to approach", "what's the strategy", "build a plan", or any multi-step problem requiring skill orchestration.

日本語の概要は準備中です。原文の説明を表示しています。

MikeCheng1208/BattleTree22026年7月22日 更新

MikeCheng1208 のスキルをすべて見る

このスキルの問題を報告する