Businesses must innovate at a much faster rate to stay ahead of the competition. They must significantly improve how they develop and deploy the software that is the foundation for innovation.
Not only must businesses adopt agile practices and deploy on the cloud but they must also replace their large, cumbersome monolithic applications with microservices.
In order to ensure services are loosely coupled, each service has its own private database. As a result, when developing microservices you must tackle the problem of distributed data management.
You must implement business transactions that span services but two-phase commit (2PC) is rarely an option.
You must implement queries that retrieve data from multiple services.
For most applications, the way to make microservices work and to manage distributed data successfully is to use sagas and CQRS views. In such an architecture, services communicate asynchronously using domain events, and command/reply messages.
Sagas are a transaction model for the microservice architecture. A saga is a sequence of local transactions. Each local transaction updates the data in one service and sends a message/event that triggers the next transaction.
Command Query Responsibility Segregation (CQRS) views are a way to implement queries that span services in a microservice architecture. A CQRS view is a replica of data from one or more services that is optimized for a particular set of queries. The service that maintains the view does so by subscribing to domain events. Whenever a service, updates its data it publishes a domain event.
You can use an asynchronous architecture to solve the distributed data management challenges in a microservices architecture. However, one major challenge with implementing an asynchronous architecture is atomically updating the database and sending a message.
Consider, for example, the Create Order
use case.
The service that implements this use case must perform two operations: insert a row into the ORDER table and publish an OrderCreated
event.
It is essential that both operations are done atomically.
If only one operation happened because of a failure then the system would behave incorrectly.
The standard way to atomically update state and publish a message is to use a distributed transaction involving a database and a message broker. However, for the reasons described earlier this is exactly what we do not want to do.
Eventuate provides two solutions to this problem: