This is a transaction management sample solution that demonstrates how to maintain data consistency across services in a microservices architecture by using Saga pattern.
Services are implemented through choreography-based sagas, which means that all participants are loosely coupled as they don't have direct knowledge of each other. Participants 'simply' subscribe to each other’s events and respond accordingly.
-
The
Order API
is a Java/Spring Boot RESTful service with routes to create a new order and get details of an existing order. -
The
Order Service
is a saga participant written in Java/Spring Boot that receives requests from the Order API. It starts local transactions with a distributed database (Datastax Cassandra) to create a new order or query info about an existing order. After the creation of these local transactions, it publishes order events to the message broker (Apache Kafka). Additionally, there is an event handler that subscribes to aCustomer Topic
to receive customer events. -
The
Customer API
is a Java/Spring Boot RESTful service with a route to create a new customer. -
The
Customer Service
is a saga participant written in Java/Spring Boot that receives requests from the Customer API. It starts local transactions with a distributed database (Datastax Cassandra) to create a new customer. After the creation of these local transactions, it publishes customer events to the message broker (Apache Kafka). Additionally, there is an event handler that subscribes to anOrder Topic
to receive order events.
-
It is not mandatory to use a highly scalable distributed NoSQL database (like Datastax Cassandra) for local transactions for each saga participant, you can use a SQL or NoSQL database of your choice.
-
It is not mandatory to use Apache Kafka as a message broker, you can use another one of your choice (like RabbitMQ, Azure Event Hub, etc).
-
The
Order Service
creates anOrder
in a PENDING state and publishes anOrderCreated
event. -
The
Customer Service
receives theOrderCreated
event and attempts to reserve credit for that order. It publishes aCreditReserved
event and the order state is still PENDING. -
The
Order Service
receives theCreditReceived
event and changes the order state to APPROVED.
-
The
Order Service
creates anOrder
in a PENDING state and publishes anOrderCreated
event. -
The
Customer Service
receives theOrderCreated
event and attempts to reserve credit for that order. It publishes aCreditLimitExceeded
event and the order state is still PENDING. -
The
Order Service
receives theCreditLimitExceeded
event and changes the order state to REJECTED.
- Java 8 (OpenJDK or Oracle JDK)
- Docker for Windows or Linux
Go to src/order
and build the application:
$ docker build -t order-api .
$ docker run -p 8080:8080 -t order-api
Next you can use the Order API through Swagger UI on http://localhost:8080/swagger-ui.html.
If you want to run services without Docker container, run this script on src/order
:
./gradlew assemble
The script above will download Gradle automatically and will build the API. Now you can run the API with this command:
./gradlew build && java -jar order-api/build/libs/order-api-*.jar
Next you can use the Order API through Swagger UI on http://localhost:8080/swagger-ui.html.