Skip to main content

Checkout Process: Saga and Failure Model

The buy process spans several services. This page describes how their work is coordinated at runtime, and how failures are handled.

Coordination Style​

Coordination is purely event-based. There is no orchestrator component, and no service drives the process centrally. Each participant subscribes to the event that concludes the preceding step, performs a local transaction, and publishes the outcome as a new event. The events are exchanged via dapr pub/sub as described in the component diagram.

The saga is essentially linear. The steps form a chain rather than a graph, and no step waits for several predecessors to complete. Only two events have more than one subscriber, and in both cases the additional subscriber performs work that the rest of the chain does not depend on.

Buy Saga​

StepTriggered byServiceActionPublishes
1Order is placedOrderRecords the order with status PLACEDorder/order/created
2order/order/createdInventoryReserves the ProductItems for the orderinventory/product-item/reservation-succeeded or reservation-failed
3inventory/product-item/reservation-succeededDiscountValidates the order to check if the discounts can still be applieddiscount/order/validation-succeeded or validation-failed
4discount/order/validation-succeededPaymentStarts the payment processpayment/payment/payment-enabled, then payment-processed or payment-failed
5payment/payment/payment-enabledShipmentCreates the shipments for the ordershipment/shipment/created or creation-failed
6shipment/shipment/created, shipment/shipment/status-updatedInventoryUpdates the inventory status based on the shipment status--

Two steps have a second subscriber alongside the one that continues the chain:

  • On discount/order/validation-succeeded, the Invoice service creates the invoice and publishes invoice/invoice/created.
  • On payment/payment/payment-enabled, the Inventory service sends the reserved inventory to fulfillment.

The ShoppingCart service also subscribes to order/order/created to remove the ordered items from the cart, and the Return service imports the Order and later the Shipment so that returns can reference them. Neither is part of the buy saga itself.

Failure Model​

The saga distinguishes two classes of error.

Transient errors​

Errors that are expected to resolve on their own are handled by retrying. Most processes retry indefinitely. The underlying assumption is that a service which is temporarily unavailable becomes available again after some time, so the step eventually succeeds without intervention. Transient errors are therefore not represented as events, and they do not abort the saga.

Final failures​

Errors that will not resolve by retrying are communicated explicitly, as a dedicated event. There is no central coordinator that detects them or decides what to do: the service that detects the failure publishes the corresponding failure event, and each affected participant reacts by undoing its own local work.

Detected byFailure eventReacting serviceCompensating action
Discountdiscount/order/validation-failedInventoryReleases the product items related to the order
Paymentpayment/payment/payment-failedInventoryReleases the product items related to the order
Shipmentshipment/shipment/creation-failedOrderTriggers order compensation and publishes order/order-compensation/created

Consistency​

Because each step commits locally and the outcome travels as an event, the participating services are not consistent with each other for the duration of the saga, and in particular while a compensation is still propagating. This is an accepted consequence of the loosely coupled, event-based coordination chosen in ADR-6 and ADR-7.