Saga
Fleeting- External reference: https://www.infoq.com/articles/saga-orchestration-outbox/
- External reference: https://microservices.io/patterns/data/saga.html
- External reference: http://chrisrichardson.net/post/microservices/2019/07/09/developing-sagas-part-1.html
Saga Orchestration for Microservices Using the Outbox Pattern
Sagas allow for the implementation of long-running, distributed business transactions, executing a set of operations across multiple microservices, applying consistent all-or-nothing semantics.
goal is to create loosely coupled, independent services with as little interaction as possible,
multiple services need to act in concert to achieve a consistent outcome
outbox pattern achieves eventually consistent data exchange, without depending on the synchronous availability of all participants
There are two general ways for implementing distributed Sagas—choreography and orchestration
choreography approach, one participating service sends a message to the next after it has executed its local transaction.
With orchestration, on the other hand, there’s one coordinating service that invokes one participant after the other.
You have applied the Database per Service pattern. Each service has its own database
How to implement transactions that span services?
2PC is not an option
saga is a sequence of local transactions. Each local transaction updates the database and publishes a message or event to trigger the next local transaction in the saga. If a local transaction fails because it violates a business rule then the saga executes a series of compensating transactions that undo the changes that were made by the preceding local transactions
two ways of coordination sagas:
- Choreography - each local transaction publishes domain events that trigger local transactions in other services
- Orchestration - an orchestrator (object) tells the participants what local transactions to execute
maintain data consistency across multiple services without using distributed transactions
programming model is more complex
must design compensating transactions that explicitly undo changes made earlier in a saga.
in order to ensure loose coupling each service’s data is private
— http://chrisrichardson.net/post/microservices/2019/07/09/developing-sagas-part-1.html
Unlike in a monolithic application, you no longer have a single database that any module of the application can update. As a result, one of the key challenges that you will face is maintaining data consistency across services.
— http://chrisrichardson.net/post/microservices/2019/07/09/developing-sagas-part-1.html
you might consider using distributed transactions a.k.a. two phase commit (2PC)
— http://chrisrichardson.net/post/microservices/2019/07/09/developing-sagas-part-1.html
using 2PC is generally a bad idea a microservice architecture
— http://chrisrichardson.net/post/microservices/2019/07/09/developing-sagas-part-1.html
must write compensating transactions that explicitly undo those changes.
— http://chrisrichardson.net/post/microservices/2019/07/09/developing-sagas-part-1.html
use of a PENDING state is an example of what is known as a semantic lock counter-measure. It prevents another transaction/saga from updating the Order while it is in the process of being created
— http://chrisrichardson.net/post/microservices/2019/07/09/developing-sagas-part-1.html