Awesome-claude-code consistency-patterns-knowledge

Consistency Patterns knowledge base. Provides strong vs eventual consistency, idempotency keys, optimistic/pessimistic locking, conflict resolution, and saga compensation patterns for distributed systems audits.

install
source · Clone the upstream repo
git clone https://github.com/dykyi-roman/awesome-claude-code
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/dykyi-roman/awesome-claude-code "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/consistency-patterns-knowledge" ~/.claude/skills/dykyi-roman-awesome-claude-code-consistency-patterns-knowledge && rm -rf "$T"
manifest: skills/consistency-patterns-knowledge/SKILL.md
source content

Consistency Patterns Knowledge Base

Quick reference for consistency guarantees, locking strategies, idempotency, and conflict resolution in distributed PHP applications.

Strong vs Eventual Consistency

┌─────────────────────────────────────────────────────────────────────────────┐
│                     CONSISTENCY DECISION TREE                                │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│                   Is data safety-critical?                                    │
│                      (money, inventory)                                       │
│                        /          \                                           │
│                      YES           NO                                         │
│                      /              \                                         │
│              Single write      Can tolerate                                   │
│              location?         stale reads?                                   │
│               /      \           /       \                                    │
│             YES      NO        YES       NO                                  │
│              |        |         |          |                                  │
│              ▼        ▼         ▼          ▼                                  │
│          ┌───────┐ ┌────────┐ ┌────────┐ ┌──────────┐                        │
│          │Strong │ │Saga +  │ │Eventual│ │Lineariz- │                        │
│          │(ACID) │ │Compen- │ │Consist.│ │able      │                        │
│          │       │ │sation  │ │+ TTL   │ │Reads     │                        │
│          └───────┘ └────────┘ └────────┘ └──────────┘                        │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘
PropertyStrong ConsistencyEventual Consistency
GuaranteeAll reads return latest writeReads may return stale data temporarily
LatencyHigher (synchronous coordination)Lower (async propagation)
AvailabilityLower (CAP theorem trade-off)Higher (tolerates partitions)
ScalabilityLimited by coordinationHighly scalable
ComplexitySimpler app logic, harder infraSimpler infra, harder app logic
Use CasesFinancial transactions, inventorySocial feeds, analytics, caches
PHP PatternDB transactions, SELECT FOR UPDATEEvent-driven sync, CQRS read models

Idempotency Keys

Overview

Idempotency ensures that performing the same operation multiple times produces the same result. Critical for payment processing, message handling, and API retries.

AspectDetails
WhatUnique key identifying a specific operation attempt
WhySafe retries, at-least-once delivery semantics, duplicate prevention
FormatUUIDv4 or
{client-id}:{operation}:{unique-ref}
StorageRedis (fast, TTL) or DB (durable, queryable)
TTL24-72 hours depending on retry window

Delivery Guarantees

GuaranteeDescriptionIdempotency Needed?
At-most-onceFire and forget, may lose messagesNo
At-least-onceRetries until ACK, may duplicateYes
Exactly-onceProcess exactly once (hard)Built-in deduplication

Idempotency Middleware (PSR-15)

<?php

declare(strict_types=1);

namespace Infrastructure\Http\Middleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

final readonly class IdempotencyMiddleware implements MiddlewareInterface
{
    private const string HEADER = 'Idempotency-Key';

    public function __construct(
        private \Redis $redis,
        private int $ttlSeconds = 86400,
    ) {}

    public function process(
        ServerRequestInterface $request,
        RequestHandlerInterface $handler,
    ): ResponseInterface {
        if ($request->getMethod() === 'GET') {
            return $handler->handle($request);
        }

        $key = $request->getHeaderLine(self::HEADER);
        if ($key === '') {
            return $handler->handle($request);
        }

        $cacheKey = sprintf('idempotency:%s', $key);
        $cached = $this->redis->get($cacheKey);

        if ($cached !== false) {
            return unserialize($cached, ['allowed_classes' => true]);
        }

        $response = $handler->handle($request);

        $this->redis->setex($cacheKey, $this->ttlSeconds, serialize($response));

        return $response;
    }
}

Optimistic Locking

Assumes conflicts are rare. Reads a version, performs work, writes only if version unchanged.

ComponentDescription
MechanismVersion column incremented on each update
Conflict Detection
WHERE version = :expected
in UPDATE
On ConflictThrow exception, retry or return error
Best ForRead-heavy workloads, low contention
Doctrine
#[ORM\Version]
attribute on integer/datetime column

Doctrine Versioned Entity

<?php

declare(strict_types=1);

namespace Domain\Model;

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Table(name: 'products')]
final class Product
{
    #[ORM\Id]
    #[ORM\Column(type: 'string', length: 36)]
    private string $id;

    #[ORM\Column(type: 'string', length: 255)]
    private string $name;

    #[ORM\Column(type: 'integer')]
    private int $stock;

    #[ORM\Version]
    #[ORM\Column(type: 'integer')]
    private int $version = 1;

    public function __construct(string $id, string $name, int $stock)
    {
        $this->id = $id;
        $this->name = $name;
        $this->stock = $stock;
    }

    public function decrementStock(int $quantity): void
    {
        if ($this->stock < $quantity) {
            throw new InsufficientStockException($this->id, $this->stock, $quantity);
        }

        $this->stock -= $quantity;
    }

    public function getVersion(): int
    {
        return $this->version;
    }
}

Handling Optimistic Lock Failures

<?php

declare(strict_types=1);

namespace Application\UseCase;

use Doctrine\ORM\OptimisticLockException;

final readonly class DecrementStockUseCase
{
    public function __construct(
        private ProductRepositoryInterface $repository,
        private int $maxRetries = 3,
    ) {}

    public function execute(string $productId, int $quantity): void
    {
        $attempt = 0;

        while ($attempt < $this->maxRetries) {
            try {
                $product = $this->repository->findById($productId);
                $product->decrementStock($quantity);
                $this->repository->save($product);

                return;
            } catch (OptimisticLockException) {
                $attempt++;
                if ($attempt >= $this->maxRetries) {
                    throw new ConcurrencyConflictException($productId);
                }
                usleep(random_int(10_000, 50_000));
            }
        }
    }
}

Pessimistic Locking

Assumes conflicts are likely. Acquires a lock before reading, blocks other transactions.

Lock TypeSQLBehavior
Exclusive (FOR UPDATE)
SELECT ... FOR UPDATE
Blocks reads and writes
Shared (FOR SHARE)
SELECT ... FOR SHARE
Allows reads, blocks writes
NOWAIT
SELECT ... FOR UPDATE NOWAIT
Fails immediately if locked
SKIP LOCKED
SELECT ... FOR UPDATE SKIP LOCKED
Skips locked rows (queue pattern)

Deadlock Prevention Rules

  1. Always acquire locks in consistent order (e.g., by entity ID ascending)
  2. Use lock timeouts (
    SET innodb_lock_wait_timeout = 5
    )
  3. Keep transactions short (< 1 second)
  4. Avoid user interaction within transactions

Conflict Resolution Strategies

StrategyDescriptionConsistencyComplexity
Last Write Wins (LWW)Latest timestamp winsWeakLow
First Write WinsFirst write preserved, reject subsequentStrongLow
Merge FunctionCustom logic merges conflicting writesApplication-definedHigh
CRDTsConflict-free Replicated Data TypesEventual (mathematically guaranteed)Medium
Manual ResolutionHuman decides on conflictStrongestVariable

CRDT Basics

CRDT TypeOperationsExample Use
G-CounterIncrement onlyPage view counter
PN-CounterIncrement and decrementInventory count
G-SetAdd onlyTag collection
OR-SetAdd and removeShopping cart items
LWW-RegisterLast write wins registerUser profile fields

Saga Compensation vs Distributed Transactions

AspectDistributed Transaction (2PC)Saga Pattern
CoordinationTransaction coordinatorChoreography or orchestration
LockingHolds locks across servicesNo cross-service locks
ConsistencyStrong (ACID)Eventual (compensating actions)
AvailabilityLower (blocking)Higher (non-blocking)
ComplexitySimpler logic, complex infraComplex logic, simpler infra
Failure HandlingRollbackCompensating transactions
LatencyHigher (2-phase commit)Lower (async steps)
ScalabilityPoor (locks span services)Good (independent services)

Redis Atomic Operations

<?php

declare(strict_types=1);

namespace Infrastructure\Lock;

final readonly class RedisAtomicOperations
{
    public function __construct(
        private \Redis $redis,
    ) {}

    public function acquireLock(string $resource, string $token, int $ttlMs): bool
    {
        return $this->redis->set(
            sprintf('lock:%s', $resource),
            $token,
            ['NX', 'PX' => $ttlMs],
        ) === true;
    }

    public function releaseLock(string $resource, string $token): bool
    {
        $script = <<<'LUA'
            if redis.call("get", KEYS[1]) == ARGV[1] then
                return redis.call("del", KEYS[1])
            else
                return 0
            end
        LUA;

        return $this->redis->eval(
            $script,
            [sprintf('lock:%s', $resource), $token],
            1,
        ) === 1;
    }

    public function compareAndSwap(string $key, string $expected, string $newValue, int $ttl): bool
    {
        $script = <<<'LUA'
            if redis.call("get", KEYS[1]) == ARGV[1] then
                return redis.call("setex", KEYS[1], ARGV[3], ARGV[2])
            else
                return 0
            end
        LUA;

        return $this->redis->eval(
            $script,
            [$key, $expected, $newValue, (string) $ttl],
            1,
        ) !== 0;
    }
}

Common Violations Quick Reference

ViolationWhere to LookSeverity
No locking on shared mutable stateRepositories, aggregatesCritical
Missing idempotency on payment endpointsAPI controllers, handlersCritical
Optimistic lock exception swallowed silentlyCatch blocks, use casesCritical
Long-running pessimistic locksTransaction scopesWarning
No retry on optimistic lock failureUse cases, command handlersWarning
Distributed transaction across servicesService-to-service callsCritical
Missing version field on aggregatesDoctrine entitiesWarning
Idempotency key without TTLRedis/cache storesWarning

Detection Patterns

# Optimistic locking
Grep: "@Version|ORM\\\\Version|version" --glob "**/Entity/**/*.php"
Grep: "OptimisticLockException|StaleObjectStateException" --glob "**/*.php"
Grep: "LOCK_OPTIMISTIC|LockMode::OPTIMISTIC" --glob "**/*.php"

# Pessimistic locking
Grep: "FOR UPDATE|FOR SHARE|LOCK_PESSIMISTIC" --glob "**/*.php"
Grep: "LockMode::PESSIMISTIC|SKIP LOCKED|NOWAIT" --glob "**/*.php"

# Idempotency patterns
Grep: "Idempotency|idempotency.key|IdempotencyKey" --glob "**/*.php"
Grep: "deduplication|dedup|duplicate.check" --glob "**/*.php"

# Distributed locks
Grep: "SETNX|NX.*PX|redis.*lock|Lock::acquire" --glob "**/*.php"
Grep: "Redlock|RedisLock|LockFactory" --glob "**/*.php"

# Saga patterns
Grep: "compensat|SagaStep|SagaOrchestrator" --glob "**/*.php"
Grep: "CompensatingAction|rollback|undo" --glob "**/Saga/**/*.php"

# Consistency indicators
Grep: "EventualConsistency|ReadModel|Projection" --glob "**/*.php"
Grep: "transaction|beginTransaction|commit|rollback" --glob "**/*.php"

References

For detailed information, load these reference files:

  • references/locking-patterns.md
    — Optimistic locking, pessimistic locking, distributed locks, Redlock algorithm, Symfony Lock component
  • references/idempotency-patterns.md
    — Idempotency key generation, deduplication store, PSR-15 middleware, delivery guarantees, non-idempotent operations