Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
giuseppe-trisciuoglio avatar

Spring Boot Saga Pattern

  • 1.7k installs
  • 311 repo stars
  • Updated June 22, 2026
  • giuseppe-trisciuoglio/developer-kit

How to implement distributed transactions across microservices using saga pattern with compensating transactions, message brokers, and eventual consistency.

About

Teaches distributed transaction patterns for Spring Boot microservices, replacing two-phase commit with saga pattern (choreography or orchestration). Developers use this when building multi-service workflows requiring eventual consistency, compensating transactions, and failure recovery. Covers both event-driven (Kafka/RabbitMQ) and centralized (Axon Framework) approaches, with emphasis on idempotent compensations, saga state persistence, message broker configuration, and observability through metrics and monitoring.

  • Choreography and orchestration saga implementations for Spring Boot
  • Idempotent compensating transactions and state persistence patterns
  • Kafka and RabbitMQ configuration with exactly-once semantics
  • Saga monitoring: duration tracking, compensation counts, failure rates, SLA alerts
  • Complete flow examples with event handlers, aggregates, and error recovery

Spring Boot Saga Pattern by the numbers

  • 1,658 all-time installs (skills.sh)
  • +55 installs in the week ending Jul 28, 2026 (Skillselion tracking)
  • Ranked #282 of 4,386 Backend & APIs skills by installs in the Skillselion catalog
  • Security screen: MEDIUM risk (skills.sh audit)
  • Data as of Jul 28, 2026 (Skillselion catalog sync)
At a glance

spring-boot-saga-pattern capabilities & compatibility

Capabilities
design choreography based sagas with event handl · design orchestration based sagas with centralize · implement idempotent compensating transactions · configure kafka and rabbitmq with exactly once s · persist and recover saga state from database · monitor saga execution and track failures · handle circuit breakers and dead letter queues
Works with
kafka · github
Use cases
api development · orchestration · debugging
Platforms
macOS · Windows · Linux
Runs
Hosted SaaS
Pricing
Free
From the docs

What spring-boot-saga-pattern says it does

Replaces two-phase commit with a sequence of local transactions and compensating actions. Supports choreography (event-driven) and orchestration (centralized coordinator) approaches with Kafka, Rabbit
spring-boot-saga-pattern.md
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill spring-boot-saga-pattern

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs1.7k
repo stars311
Security audit3 / 3 scanners passed
Last updatedJune 22, 2026
Repositorygiuseppe-trisciuoglio/developer-kit

What it does

Implement distributed transactions across microservices using saga pattern with event-driven or orchestrated coordination.

Who is it for?

Microservices architectures requiring distributed transactions, eventual consistency, complex business workflows spanning multiple services, brownfield systems replacing 2PC.

Skip if: Single-service monoliths requiring strong consistency, systems needing immediate atomic guarantees, simple transactional workflows without compensations.

When should I use this skill?

Building distributed transactions, replacing 2PC, implementing compensating transactions, ensuring eventual consistency, coordinating complex multi-service processes, handling rollback across services.

What you get

Developers can design and implement choreography or orchestration sagas, coordinate multi-service workflows, handle compensations idempotently, and monitor saga lifecycle.

  • Saga flow diagrams and transaction mappings
  • Choreography or orchestration service implementations
  • Idempotent compensating transaction handlers

By the numbers

  • Supports 2 approaches: choreography (event-driven) and orchestration (centralized coordinator)
  • Replaces 2PC with sequence of local transactions
  • Default saga step timeout: 30s (configurable)

Files

SKILL.mdMarkdownGitHub ↗

Spring Boot Saga Pattern

Overview

Implements distributed transactions across microservices using the Saga Pattern. Replaces two-phase commit with a sequence of local transactions and compensating actions. Supports choreography (event-driven) and orchestration (centralized coordinator) approaches with Kafka, RabbitMQ, or Axon Framework.

When to Use

  • Building distributed transactions across multiple microservices
  • Replacing two-phase commit (2PC) with a more scalable solution
  • Handling transaction rollback when a service fails
  • Ensuring eventual consistency in microservices architecture
  • Implementing compensating transactions for failed operations
  • Coordinating complex business processes spanning multiple services

Trigger phrases: distributed transactions, saga pattern, compensating transactions, microservices transaction, eventual consistency, rollback across services, orchestration pattern, choreography pattern

Instructions

1. Design Transaction Flow

Map the sequence of operations and their compensating transactions:

Order → Payment → Inventory → Shipment
  ↓        ↓        ↓          ↓
Cancel  Refund   Release    Cancel

Validation: Verify every forward step has a corresponding compensation.

2. Choose Implementation Approach

ApproachUse CaseStack
ChoreographyGreenfield, few participantsSpring Cloud Stream + Kafka/RabbitMQ
OrchestrationComplex workflows, brownfieldAxon Framework, Eventuate Tram, Camunda

Validation: Review team expertise and system complexity before choosing.

3. Implement Services with Local Transactions

Each service completes its local ACID transaction atomically:

@Service
@RequiredArgsConstructor
public class OrderService {
    private final OrderRepository orderRepository;
    private final KafkaTemplate<String, Object> kafka;

    @Transactional
    public Order createOrder(CreateOrderCommand cmd) {
        Order order = orderRepository.save(new Order(cmd.orderId(), cmd.items()));
        kafka.send("order.created", new OrderCreatedEvent(order.getId(), order.getItems()));
        return order;
    }
}

Validation: Test that local transaction commits before event is published.

4. Implement Compensating Transactions

Every forward operation requires an idempotent compensation:

@Service
@RequiredArgsConstructor
public class PaymentService {
    private final PaymentRepository paymentRepository;
    private final KafkaTemplate<String, Object> kafka;

    public void processPayment(PaymentRequest request) {
        Payment payment = paymentRepository.save(new Payment(request.orderId(), request.amount()));
        kafka.send("payment.processed", new PaymentProcessedEvent(payment.getId(), request.orderId()));
    }

    @Transactional
    public void refundPayment(String paymentId) {
        paymentRepository.findById(paymentId)
            .ifPresent(p -> {
                p.setStatus(REFUNDED);
                paymentRepository.save(p);
                kafka.send("payment.refunded", new PaymentRefundedEvent(paymentId));
            });
    }
}

Validation: Confirm compensation can execute safely multiple times (idempotency).

5. Set Up Message Broker

Configure Kafka with idempotent consumers:

@Configuration
@EnableKafka
public class KafkaConfig {
    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, Object> kafkaListenerContainerFactory(
            ConsumerFactory<String, Object> consumerFactory) {
        ConcurrentKafkaListenerContainerFactory<String, Object> factory =
            new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory);
        factory.setCommonErrorHandler(new DefaultErrorHandler());
        return factory;
    }
}

Validation: Enable transactional ID and verify exactly-once semantics.

6. Implement Saga Orchestrator (Orchestration Only)

@Service
@RequiredArgsConstructor
public class OrderSagaOrchestrator {
    private final KafkaTemplate<String, Object> kafka;
    private final SagaStateRepository sagaStateRepo;

    public void startSaga(OrderRequest request) {
        String sagaId = UUID.randomUUID().toString();
        sagaStateRepo.save(new SagaState(sagaId, STARTED, LocalDateTime.now()));
        kafka.send("saga.order.start", new StartOrderSagaCommand(sagaId, request));
    }

    @KafkaListener(topics = "payment.failed")
    public void handlePaymentFailed(PaymentFailedEvent event) {
        kafka.send("order.compensate", new CompensateOrderCommand(event.getSagaId()));
        kafka.send("inventory.compensate", new ReleaseInventoryCommand(event.getSagaId()));
        sagaStateRepo.updateStatus(event.getSagaId(), FAILED);
    }
}

Validation: Verify saga state persists before sending commands. Check compensation triggers on each failure path.

7. Implement Event Handlers (Choreography Only)

@Service
public class OrderEventHandler {
    private final OrderService orderService;
    private final KafkaTemplate<String, Object> kafka;

    @KafkaListener(topics = "payment.processed", groupId = "order-service")
    public void onPaymentProcessed(PaymentProcessedEvent event) {
        try {
            InventoryReservedEvent result = orderService.reserveInventory(event.toInventoryRequest());
            kafka.send("inventory.reserved", result);
        } catch (InsufficientInventoryException e) {
            kafka.send("inventory.insufficient", new InsufficientInventoryEvent(event.getOrderId(), event.getPaymentId()));
        }
    }
}

Validation: Test that each event handler correctly triggers the next step or compensation.

8. Add Monitoring and Observability

@Configuration
public class SagaMetricsConfig {
    @Bean
    public MeterRegistry meterRegistry() {
        return new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
    }
}

Track: saga execution duration, compensation count, failure rate, stuck sagas.

Validation: Set up alerts for sagas exceeding expected duration.

Best Practices

Design:

  • Make compensating transactions idempotent using database constraints or deduplication tables
  • Use immutable events (Java records) to prevent accidental mutation
  • Store saga state in persistent storage for recovery

Error Handling:

  • Implement circuit breakers for inter-service calls
  • Use dead-letter queues for messages exceeding retry limits
  • Set appropriate timeouts per saga step (30s default, configurable)

Monitoring:

  • Track saga status: PENDING, COMPLETED, COMPENSATING, FAILED
  • Monitor compensation execution time
  • Alert when sagas exceed SLA duration

Constraints and Warnings

  • Every forward transaction MUST have a corresponding compensating transaction
  • Compensating transactions MUST be idempotent to handle retry scenarios
  • Saga state MUST be persisted to handle failures and recovery
  • Never use synchronous communication between saga participants
  • Sagas provide eventual consistency, not strong consistency
  • Test all failure scenarios including partial failures
  • Consider Axon Framework or Eventuate for complex orchestrations
  • Ensure message brokers are highly available

Examples

Choreography-Based Saga

// Application.java
@SpringBootApplication
@EnableKafka
@EnableKafkaListeners
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

// Event Classes (immutable)
public record OrderCreatedEvent(String orderId, List<OrderItem> items) {}
public record PaymentProcessedEvent(String paymentId, String orderId) {}
public record InventoryReservedEvent(String reservationId, String orderId) {}
public record PaymentFailedEvent(String orderId, String reason) {}
public record InsufficientInventoryEvent(String orderId, String paymentId) {}

// OrderService with compensation
@Service
@RequiredArgsConstructor
public class OrderService {
    private final OrderRepository orderRepository;
    private final KafkaTemplate<String, Object> kafka;

    @KafkaListener(topics = "payment.failed", groupId = "order-service")
    public void handleCompensation(PaymentFailedEvent event) {
        orderRepository.findByOrderId(event.orderId())
            .ifPresent(order -> {
                order.setStatus(CANCELLED);
                orderRepository.save(order);
            });
    }
}

Orchestration-Based Saga with Axon Framework

// Command
@Aggregate
public class OrderAggregate {
    @AggregateIdentifier
    private String orderId;

    @CommandHandler
    public OrderAggregate(CreateOrderCommand cmd) {
        apply(new OrderCreatedEvent(cmd.orderId(), cmd.items()));
    }

    @EventSourcingHandler
    public void on(OrderCreatedEvent event) {
        this.orderId = event.orderId();
    }

    @CommandHandler
    public void handle(CancelOrderCommand cmd) {
        apply(new OrderCancelledEvent(cmd.orderId(), cmd.reason()));
    }
}

References

  • Saga Pattern Definition
  • Choreography Implementation
  • Orchestration Implementation
  • Compensating Transactions
  • State Management
  • Error Handling and Retry
  • Testing Strategies
  • Pitfalls and Solutions
  • Examples

Related skills

Forks & variants (1)

Spring Boot Saga Pattern has 1 known copy in the catalog totaling 20 installs. They canonicalize to this original listing.

How it compares

Pick spring-boot-saga-pattern for event-choreography in Spring Boot; pick orchestrator-based saga guides when a central coordinator is already chosen.

FAQ

What is the key difference between choreography and orchestration sagas?

Choreography uses event-driven communication where each service listens to events and emits its own (Spring Cloud Stream + Kafka/RabbitMQ). Orchestration uses a central coordinator that commands participants (Axon Framework, Eventuate). Choreography suits greenfield with few part

Why must compensating transactions be idempotent?

Idempotency ensures safe retries if compensation fails or the message is delivered multiple times. Implement via database constraints, deduplication tables, or unique request IDs tracked in the compensation.

How do I handle saga recovery after a failure?

Persist saga state before sending commands. On failure, retrieve state from storage and re-trigger compensation flow. Use dead-letter queues for messages exceeding retry limits and set timeouts per saga step (30s default).

Is Spring Boot Saga Pattern safe to install?

skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

Backend & APIsbackendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.