This project demonstrates distributed SAGA orchestration using Temporal.io and Spring Boot/Java. It features four self-contained microservices choreographed by a central Temporal orchestrator to maintain data consistency across distributed transactions.
The system transitions an Order through reserving inventory, processing payment, and shipping the product. If any step fails, Temporal's built-in Saga functionality will automatically execute rollback activities (e.g., releasing inventory or refunding payment).
- Temporal Server & UI: Core orchestration engine and web dashboard.
- Order Service: Exposes REST APIs, manages local database persistence, and runs the
OrderWorkflowwhich acts as the SAGA orchestrator. - Inventory Service: Mock Temporal worker handling
reserveInventoryandreleaseInventory. - Payment Service: Mock Temporal worker handling
processPaymentandrefundPayment. - Shipping Service: Mock Temporal worker handling
shipProductandcancelShipping.
-
Start Docker Desktop: Ensure your Docker daemon is running.
-
Pull Images and Start Containers: Open your terminal in the root of this project and run:
docker compose up --build -d
-
Verify Services:
- Temporal UI: http://localhost:8080
- Order Service APIs:
http://localhost:8081/api/orders
Specific endpoints and flags have been built to demonstrate Temporal's robust handling of typical microservice failures.
Create an order that successfully reserves inventory, charges payment, and ships.
curl -X POST http://localhost:8081/api/orders \
-H "Content-Type: application/json" \
-d '{"orderId": "100", "amount": 50.0}'- Verification: Open the Temporal UI (http://localhost:8080), locate
OrderFlow-100, and observe it transition through all 4 activities successfully.
Demonstrate a failure in the Payment service. We'll pass simulatePaymentFailure=true which forces the payment activity to fail after exhausting its retries (configured for 3 attempts).
curl -X POST "http://localhost:8081/api/orders?simulatePaymentFailure=true" \
-H "Content-Type: application/json" \
-d '{"orderId": "200", "amount": 75.0}'-
SAGA Verification:
- Open the Temporal UI and monitor
OrderFlow-200. - The
reserveInventoryactivity will succeed. - The
processPaymentactivity will fail multiple times (Pending state). - Once retries are exhausted, the workflow catches the failure, triggers
saga.compensate(), and executesreleaseInventoryand cancels the order in DB! - Query the workflow status:
curl http://localhost:8081/api/orders/200/workflow-status(Will returnCANCELED_DUE_TO_FAILURE).
- Open the Temporal UI and monitor
A failure at the end of the line will trigger rollbacks for both payment and inventory.
curl -X POST "http://localhost:8081/api/orders?simulateShippingFailure=true" \
-H "Content-Type: application/json" \
-d '{"orderId": "300", "amount": 100.0}'If a service goes down completely and a workflow fails, "Reset" from the Temporal UI can be used, or simply issue a new POST request.
- Open the Temporal UI (http://localhost:8080).
- Go to the Workflows list and click on the failed workflow (e.g.,
OrderFlow-200). - Click the Reset button in the top right corner (often under an actions dropdown).
- Select the First Workflow Task to restart the entire workflow execution from the beginning.
- Alternatively, because the default
WorkflowIdReusePolicyallows reusing IDs for failed workflows, you can simply run yourPOST /api/orderscurl again using the exact sameorderId. Temporal will start a fresh execution for that failed order!
To shut down the cluster and clean up:
docker compose down(Note: Order data is preserved in the Docker volume. Run docker compose down -v to wipe it)


