Comprehensive developer toolkit providing reusable skills for Java/Spring Boot, TypeScript/NestJS/React/Next.js, Python, PHP, AWS CloudFormation, AI/RAG, DevOps, and more.
82
82%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Risky
Do not use without reviewing
Implement this skill when:
Trigger phrases: distributed transactions, saga pattern, compensating transactions, microservices transaction, eventual consistency, rollback across services, orchestration pattern, choreography pattern
The Saga Pattern is an architectural pattern for managing distributed transactions in microservices. Instead of using a single ACID transaction across multiple databases, a saga breaks the transaction into a sequence of local transactions. Each local transaction updates its database and publishes an event or message to trigger the next step. If a step fails, the saga executes compensating transactions to undo the changes made by previous steps.
When implementing a saga, make these decisions:
Follow these steps to implement saga pattern for distributed transactions:
Identify all services involved in the business process. Map out the sequence of local transactions and their corresponding compensating transactions.
Select choreography (event-driven, decentralized) or orchestration (centralized coordinator) based on team expertise and system complexity.
Create events for each transaction step (OrderCreated, PaymentProcessed, InventoryReserved). Include correlationId for tracing.
Ensure each service can complete its local transaction atomically within its own database boundary.
For each forward operation, implement a compensating operation that reverses the effect (cancel order, refund payment, release inventory).
Configure Kafka or RabbitMQ with appropriate topics/queues. Implement idempotent message consumers.
Create a saga orchestrator service that tracks saga state, sends commands to participants, and handles compensations on failure.
Set up event listeners in each service that react to events from other services and trigger next steps.
Implement timeout mechanisms for each saga step. Configure dead-letter queues for messages that exceed processing time limits.
Track saga execution status, duration, and failure rates. Set up alerts for stuck or failed sagas.
Each microservice publishes events and listens to events from other services. No central coordinator.
Best for: Greenfield microservice applications with few participants
Advantages:
Disadvantages:
A central orchestrator manages the entire transaction flow and tells services what to do.
Best for: Brownfield applications, complex workflows, or when centralized control is needed
Advantages:
Disadvantages:
Identify the sequence of operations and corresponding compensating transactions:
Order → Payment → Inventory → Shipment → Notification
↓ ↓ ↓ ↓ ↓
Cancel Refund Release Cancel CancelEach service handles its local ACID transaction and publishes events or responds to commands.
Every forward transaction must have a corresponding compensating transaction. Ensure idempotency and retryability.
Implement retry logic, timeouts, and dead-letter queues for failed messages.
Spring Boot 3.x with dependencies:
Messaging: Spring Cloud Stream, Apache Kafka, RabbitMQ, Spring AMQP
Saga Frameworks: Axon Framework (4.9.0), Eventuate Tram Sagas, Camunda, Apache Camel
Persistence: Spring Data JPA, Event Sourcing (optional), Transactional Outbox Pattern
Monitoring: Spring Boot Actuator, Micrometer, Distributed Tracing (Sleuth + Zipkin)
❌ Tight Coupling: Services directly calling each other instead of using events ❌ Missing Compensations: Not implementing compensating transactions for every step ❌ Non-Idempotent Operations: Compensations that cannot be safely retried ❌ Synchronous Sagas: Waiting synchronously for each step (defeats the purpose) ❌ Lost Messages: Not handling message delivery failures ❌ No Monitoring: Running sagas without visibility into their status ❌ Shared Database: Using same database across multiple services ❌ Ignoring Network Failures: Not handling partial failures gracefully
Do not implement this pattern when:
@Transactional
public Order createOrder(OrderRequest request) {
Order order = orderRepository.save(request);
paymentService.charge(request.getPayment());
inventoryService.reserve(request.getItems());
shippingService.schedule(order);
return order;
}@Service
public class OrderSagaOrchestrator {
public OrderSummary createOrder(OrderRequest request) {
// Step 1: Create order
Order order = orderService.createOrder(request);
try {
// Step 2: Process payment
Payment payment = paymentService.processPayment(
new PaymentRequest(order.getId(), request.getAmount()));
// Step 3: Reserve inventory
InventoryReservation reservation = inventoryService.reserve(
new InventoryRequest(order.getItems()));
// Step 4: Schedule shipping
Shipment shipment = shippingService.schedule(
new ShipmentRequest(order.getId()));
return OrderSummary.completed(order, payment, reservation, shipment);
} catch (PaymentFailedException e) {
// Compensate: cancel order
orderService.cancelOrder(order.getId());
throw e;
} catch (InsufficientInventoryException e) {
// Compensate: refund payment, cancel order
paymentService.refund(payment.getId());
orderService.cancelOrder(order.getId());
throw e;
}
}
}// Event published when order is created
@EventHandler
public void on(OrderCreatedEvent event) {
// Trigger payment processing
paymentService.processPayment(event.getOrderId());
}@Service
public class OrderEventHandler {
@KafkaListener(topics = "order.created")
public void handleOrderCreated(OrderCreatedEvent event) {
try {
paymentService.processPayment(event.toPaymentRequest());
} catch (PaymentException e) {
kafkaTemplate.send("order.payment.failed", new PaymentFailedEvent(event.getOrderId()));
}
}
}
@Service
public class PaymentEventHandler {
@KafkaListener(topics = "payment.processed")
public void handlePaymentProcessed(PaymentProcessedEvent event) {
inventoryService.reserve(event.toInventoryRequest());
}
@KafkaListener(topics = "payment.failed")
public void handlePaymentFailed(PaymentFailedEvent event) {
orderService.cancelOrder(event.getOrderId());
}
}
@Service
public class InventoryEventHandler {
@KafkaListener(topics = "inventory.reserved")
public void handleInventoryReserved(InventoryReservedEvent event) {
shippingService.scheduleShipment(event.toShipmentRequest());
}
@KafkaListener(topics = "inventory.insufficient")
public void handleInsufficientInventory(InsufficientInventoryEvent event) {
// Compensate: refund payment
paymentService.refund(event.getPaymentId());
// Compensate: cancel order
orderService.cancelOrder(event.getOrderId());
}
}For detailed information, consult the following resources:
See also examples.md for complete implementation examples:
plugins
developer-kit-ai
skills
chunking-strategy
prompt-engineering
developer-kit-aws
skills
aws
aws-cli-beast
aws-cost-optimization
aws-drawio-architecture-diagrams
aws-sam-bootstrap
aws-cloudformation
aws-cloudformation-auto-scaling
references
aws-cloudformation-bedrock
references
aws-cloudformation-cloudfront
references
aws-cloudformation-cloudwatch
references
aws-cloudformation-dynamodb
references
aws-cloudformation-ec2
aws-cloudformation-ecs
references
aws-cloudformation-elasticache
aws-cloudformation-iam
references
aws-cloudformation-lambda
references
aws-cloudformation-rds
aws-cloudformation-s3
references
aws-cloudformation-security
references
aws-cloudformation-task-ecs-deploy-gh
aws-cloudformation-vpc
developer-kit-core
skills
developer-kit-java
skills
aws-lambda-java-integration
aws-rds-spring-boot-integration
aws-sdk-java-v2-bedrock
aws-sdk-java-v2-core
aws-sdk-java-v2-dynamodb
aws-sdk-java-v2-kms
aws-sdk-java-v2-lambda
aws-sdk-java-v2-messaging
aws-sdk-java-v2-rds
aws-sdk-java-v2-s3
aws-sdk-java-v2-secrets-manager
graalvm-native-image
langchain4j
langchain4j-mcp-server-patterns
langchain4j-ai-services-patterns
references
langchain4j-mcp-server-patterns
references
langchain4j-rag-implementation-patterns
references
langchain4j-spring-boot-integration
langchain4j-testing-strategies
langchain4j-tool-function-calling-patterns
langchain4j-vector-stores-configuration
references
qdrant
references
spring-ai-mcp-server-patterns
references
spring-boot-actuator
spring-boot-cache
spring-boot-crud-patterns
spring-boot-dependency-injection
spring-boot-event-driven-patterns
spring-boot-openapi-documentation
spring-boot-project-creator
spring-boot-resilience4j
spring-boot-rest-api-standards
spring-boot-saga-pattern
spring-boot-security-jwt
assets
references
scripts
spring-boot-test-patterns
spring-data-jpa
references
spring-data-neo4j
references
unit-test-application-events
unit-test-bean-validation
unit-test-boundary-conditions
unit-test-caching
unit-test-config-properties
unit-test-controller-layer
unit-test-exception-handler
unit-test-json-serialization
unit-test-mapper-converter
unit-test-parameterized
unit-test-scheduled-async
unit-test-service-layer
unit-test-utility-methods
unit-test-wiremock-rest-api
developer-kit-php
skills
aws-lambda-php-integration
developer-kit-python
skills
aws-lambda-python-integration
developer-kit-tools
developer-kit-typescript
skills
aws-lambda-typescript-integration
better-auth
drizzle-orm-patterns
dynamodb-toolbox-patterns
references
nestjs
nestjs-best-practices
nestjs-code-review
nestjs-drizzle-crud-generator
scripts
nextjs-app-router
nextjs-authentication
nextjs-code-review
nextjs-data-fetching
references
nextjs-deployment
nextjs-performance
nx-monorepo
react-code-review
react-patterns
references
shadcn-ui
tailwind-css-patterns
references
tailwind-design-system
references
turborepo-monorepo
typescript-docs
typescript-security-review
zod-validation-utilities