270 lines
7.4 KiB
Markdown
270 lines
7.4 KiB
Markdown
---
|
|
trigger: always_on
|
|
---
|
|
|
|
# Data Consistency Patterns
|
|
|
|
## When to Use This Skill
|
|
|
|
Use this skill when:
|
|
- Implementing distributed transactions across multiple services
|
|
- Handling eventual consistency in microservices
|
|
- Implementing Saga patterns for distributed workflows
|
|
- Designing compensation strategies for failed transactions
|
|
- Implementing idempotent operations
|
|
- Managing data synchronization across services
|
|
- Handling conflict resolution
|
|
- Implementing optimistic locking strategies
|
|
- Building event sourcing systems
|
|
- Ensuring data integrity in distributed systems
|
|
|
|
## Core Concepts
|
|
|
|
### ACID vs BASE
|
|
|
|
**ACID (Traditional Databases):**
|
|
- Atomicity: All or nothing
|
|
- Consistency: Data always valid
|
|
- Isolation: Concurrent transactions isolated
|
|
- Durability: Committed changes persist
|
|
|
|
**BASE (Distributed Systems):**
|
|
- Basic Availability: System available most of the time
|
|
- Soft state: State may change over time
|
|
- Eventual consistency: Consistency achieved eventually
|
|
|
|
### Consistency Models
|
|
|
|
| Model | Description | Use Case |
|
|
|-------|-------------|----------|
|
|
| **Strong** | All nodes see same data at same time | Financial transactions |
|
|
| **Weak** | No guarantees about when consistency occurs | Caching |
|
|
| **Eventual** | System becomes consistent over time | Read models, analytics |
|
|
| **Causal** | Related operations maintain order | User sessions |
|
|
|
|
### Distributed Transaction Challenges
|
|
|
|
- Network partitions
|
|
- Service failures
|
|
- Clock synchronization
|
|
- Partial failures
|
|
- Two-Phase Commit (2PC) limitations
|
|
|
|
## Saga Pattern
|
|
|
|
### Orchestration vs Choreography
|
|
|
|
| Approach | Central Control | Resilience | Complexity | Best For |
|
|
|----------|-----------------|------------|------------|----------|
|
|
| **Orchestration** | Yes (single coordinator) | Lower (SPOF) | Easier to debug | Complex workflows |
|
|
| **Choreography** | No (event-driven) | Higher | Harder to trace | Simple flows, loose coupling |
|
|
|
|
### Saga Execution Flow
|
|
|
|
```
|
|
Execute: Step1 -> Step2 -> Step3 -> Complete
|
|
| | |
|
|
v v v
|
|
Compensate: <- Step2.undo <- Step1.undo (on failure)
|
|
```
|
|
|
|
### Key Saga Interfaces
|
|
|
|
```typescript
|
|
interface SagaStep {
|
|
name: string;
|
|
execute: () => Promise<any>;
|
|
compensate: (context: any) => Promise<void>;
|
|
retry?: number;
|
|
}
|
|
|
|
interface SagaContext {
|
|
sagaId: string;
|
|
steps: SagaStep[];
|
|
currentStep: number;
|
|
data: Record<string, any>;
|
|
status: 'pending' | 'running' | 'completed' | 'compensating' | 'failed';
|
|
}
|
|
```
|
|
|
|
See [./references/REFERENCE.md](./references/REFERENCE.md) for full Saga orchestrator implementation.
|
|
|
|
## Idempotency Pattern
|
|
|
|
Ensures operations can be safely retried without side effects.
|
|
|
|
### Key Concepts
|
|
|
|
- **Idempotency Key**: Unique identifier for each operation
|
|
- **Result Storage**: Cache results to return on duplicates
|
|
- **TTL**: Time-to-live for idempotency records
|
|
|
|
### Pattern
|
|
|
|
```typescript
|
|
const key = `${operation}:${userId}:${hash(requestData)}`;
|
|
await idempotencyHandler.execute(key, () => operation());
|
|
```
|
|
|
|
See [./references/REFERENCE.md](./references/REFERENCE.md) for full implementation.
|
|
|
|
## Optimistic Locking
|
|
|
|
Prevents lost updates in concurrent scenarios using version fields.
|
|
|
|
### Pattern
|
|
|
|
```typescript
|
|
await prisma.entity.update({
|
|
where: { id, version: currentVersion },
|
|
data: { ...updates, version: { increment: 1 } }
|
|
});
|
|
```
|
|
|
|
### Prisma Schema
|
|
|
|
```prisma
|
|
model Entity {
|
|
id String @id @default(cuid())
|
|
version Int @default(1)
|
|
// ... other fields
|
|
}
|
|
```
|
|
|
|
See [./references/REFERENCE.md](./references/REFERENCE.md) for full optimistic locking service.
|
|
|
|
## CQRS Pattern
|
|
|
|
Command Query Responsibility Segregation separates read and write operations.
|
|
|
|
### Architecture
|
|
|
|
```
|
|
Write Path: Command -> Write Model -> Event -> Event Store
|
|
Read Path: Query -> Read Model (denormalized, optimized for reads)
|
|
```
|
|
|
|
### Key Benefits
|
|
|
|
- Optimized read models for query performance
|
|
- Independent scaling of read/write operations
|
|
- Eventual consistency between models
|
|
|
|
See [./references/REFERENCE.md](./references/REFERENCE.md) for implementation details.
|
|
|
|
## Conflict Resolution Strategies
|
|
|
|
| Strategy | Description | Use Case |
|
|
|----------|-------------|----------|
|
|
| **Last Write Wins** | Latest timestamp wins | Simple scenarios |
|
|
| **First Write Wins** | Earliest timestamp wins | Preserving original data |
|
|
| **Merge** | Combine both versions | Non-conflicting fields |
|
|
| **Manual** | Store for human review | Critical data conflicts |
|
|
|
|
## Outbox Pattern
|
|
|
|
Ensures reliable event publishing by storing events in the same transaction as business data.
|
|
|
|
### Flow
|
|
|
|
1. Execute business operation in transaction
|
|
2. Store event in outbox table (same transaction)
|
|
3. Background processor publishes and marks as sent
|
|
|
|
See [./references/REFERENCE.md](./references/REFERENCE.md) for implementation.
|
|
|
|
## Best Practices
|
|
|
|
### Saga Pattern
|
|
- Design compensations for every step
|
|
- Make steps idempotent for retries
|
|
- Set timeouts for saga execution
|
|
- Monitor saga execution and compensation
|
|
- Choose orchestration for complex workflows, choreography for simple ones
|
|
|
|
### Idempotency
|
|
- Generate keys from request data
|
|
- Store keys with results
|
|
- Set appropriate TTL for records
|
|
- Regularly clean expired records
|
|
|
|
### Eventual Consistency
|
|
- Accept that consistency is eventual
|
|
- Use separate read models for queries
|
|
- Define resolution strategies upfront
|
|
- Monitor consistency lag
|
|
|
|
### Optimistic Locking
|
|
- Add version fields to entities
|
|
- Implement retry with exponential backoff
|
|
- Handle conflicts gracefully
|
|
- Use for read-heavy workloads
|
|
|
|
## Common Mistakes
|
|
|
|
### No Compensation Logic
|
|
```typescript
|
|
// BAD: No compensation
|
|
steps: [{ execute: () => createOrder() }]
|
|
|
|
// GOOD: Always define compensation
|
|
steps: [{
|
|
execute: () => createOrder(),
|
|
compensate: (ctx) => cancelOrder(ctx.orderId)
|
|
}]
|
|
```
|
|
|
|
### Missing Idempotency
|
|
```typescript
|
|
// BAD: Creates duplicate on retry
|
|
await createPayment(orderId);
|
|
|
|
// GOOD: Idempotent check
|
|
const existing = await findPayment(idempotencyKey);
|
|
if (existing) return existing;
|
|
await createPayment(orderId);
|
|
```
|
|
|
|
### Ignoring Partial Failures
|
|
```typescript
|
|
// BAD: No error handling
|
|
await step1(); await step2(); await step3();
|
|
|
|
// GOOD: Saga orchestration
|
|
await sagaOrchestrator.execute(context);
|
|
```
|
|
|
|
### No Version Field
|
|
```prisma
|
|
// GOOD: Add version for optimistic locking
|
|
model Entity {
|
|
version Int @default(1)
|
|
}
|
|
```
|
|
|
|
## Quick Reference
|
|
|
|
| Pattern | Use Case | Complexity |
|
|
|---------|----------|------------|
|
|
| **Saga (Orchestrated)** | Complex multi-step workflows | High |
|
|
| **Saga (Choreography)** | Simple event-driven flows | Medium |
|
|
| **Outbox Pattern** | Guaranteed event publishing | Medium |
|
|
| **Idempotency** | Retry-safe operations | Low |
|
|
| **Optimistic Lock** | Concurrent updates | Low |
|
|
| **CQRS** | Read/write optimization | High |
|
|
| **Dead Letter Queue** | Failed message handling | Medium |
|
|
|
|
## Resources
|
|
|
|
### Internal References
|
|
- [Detailed Code Examples](./references/REFERENCE.md) - Full implementations for all patterns
|
|
- [Event-Driven Architecture](../event-driven-architecture/SKILL.md) - Event patterns
|
|
- [Error Handling Patterns](../error-handling-patterns/SKILL.md) - Error handling
|
|
- [Database & Prisma](../database-prisma/SKILL.md) - Database patterns
|
|
- [Project Rules](../project-rules/SKILL.md) - GoodGo coding standards
|
|
|
|
### External Resources
|
|
- [Saga Pattern](https://microservices.io/patterns/data/saga.html) - Saga pattern overview
|
|
- [Event Sourcing](https://martinfowler.com/eaaDev/EventSourcing.html) - Event sourcing pattern
|
|
- [CQRS Pattern](https://martinfowler.com/bliki/CQRS.html) - CQRS pattern
|