PrepZone Logo
PrepZone

Saga Choreography with Domain Events

OrderPlaced → ReserveInventory → ChargePayment → ShipOrder — compensating events on failure.

Why this matters

  • VaultCommerce checkout: OrderPlaced → ReserveInventory → PaymentAuthorized → OrderConfirmed; failures emit ReleaseInventory.
  • No central orchestrator — Kafka topics are the workflow bus.
  • Each step must be idempotent; saga state inferred from event history.
  • Contrast with orchestration (Temporal/Camunda) in system design discussions.
OrderPlaced
InventoryReserved
PaymentCaptured
PaymentFailed → ReleaseInventoryCompensate
Each service listens and publishes domain events. Failure triggers compensating events on the same log.

Happy path choreography

order-service publishes OrderPlaced. inventory-service reserves, publishes InventoryReserved. payment-service charges, publishes PaymentCaptured. shipping-service listens to PaymentCaptured. Each service owns its topic subscriptions and compensations.

Key points

  • Choreography — distributed workflow via events, no central coordinator
  • Compensating event — undo partial work (ReleaseInventory)
  • Saga — multi-step business transaction across services
  • Eventual consistency — saga completes asynchronously
  • Orchestration alternative — central state machine driving steps

Compensating transactions

Payment fails after reserve → payment-service publishes PaymentFailed → inventory-service publishes InventoryReleased. VaultCommerce uses partition key orderId so compensation events stay ordered with forward steps.

VaultCommerce rollout checklist

Before promoting changes that touch the VaultCommerce order and payment event backbone, run the staging KRaft cluster (Kafka 3.7+, Schema Registry 7.x) through a 10k events/min soak test. Compare producer request latency p99 and consumer lag per group against the pre-deploy baseline. Events chain the saga; no central brain. Document the change in the internal topic registry, attach Grafana screenshots to the change ticket, and keep an engineer on lag dashboards for 30 minutes after production rollout — roll back the service release before altering broker-level settings if lag or under-replicated partitions spike.

Java
// VaultCommerce inventory — saga step + compensation
@KafkaListener(topics = "vaultcommerce.orders.placed.v1")
public void onOrderPlaced(OrderPlaced event) {
    try {
        inventoryService.reserve(event.orderId(), event.lines());
        publisher.publish("vaultcommerce.inventory.reserved.v1", event.orderId(),
            new InventoryReserved(event.orderId()));
    } catch (InsufficientStockException e) {
        publisher.publish("vaultcommerce.orders.rejected.v1", event.orderId(),
            new OrderRejected(event.orderId(), "OUT_OF_STOCK"));
    }
}

@KafkaListener(topics = "vaultcommerce.payments.failed.v1")
public void onPaymentFailed(PaymentFailed event) {
    inventoryService.release(event.orderId());
}

Quick recall

Everything you need if you only revisit this box.

  1. Events chain the saga; no central brain.
  2. Compensating events undo forward steps.
  3. Key by orderId for step ordering.

Test yourself

Answer these before moving on — recall is what makes it stick.