The saga design pattern is a way to manage data consistency across software applications in distributed transaction scenarios. This will have non distributed transaction in each component and then sends event to trigger next transaction step in another computer. If any transaction fails, Saga will revert(compensating) each stage already completed. This pattern is defined in order to avoid locks on non local resources.
Modern micro-services promote a database per micro-service model where it provides many benefits over traditional monolithic applications. Encapsulating domain in a single unit helps each service to use best data-store, programming language and also scaling capabilities.
A transaction is a single unit of logic or work, made up of one or more number of operations. Within a transaction an event is a state change that occurs to an entity.
The execution of a business process in micro-services consists of one or more transactions. Each transaction may consists of several individual operations while system must move between consistent states to comply ACID properties. That is atomic, consistent, isolated and durable. To comply ACID ,distributed transactions should implement cross-service transaction management strategy.
- Atomicity : given set of operations all or nothing should happen
- Consistency: data should move from one valid state to another
- Isolation: concurrent or sequential still should provide the same result
- Durability: committed data must be available even at a power outage
In a context of a single database this can be achieved using commit and rollback mechanism comes under transaction management where set of operations under transaction happens under one go.
In a distributed application we can ‘t apply commit rollback mechanism as due to the distributed nature, Compensating pattern is used instead. Compensating a transaction can’t be a automatic task due to its complexity and should be designed according to the business.
Saga pattern provides transaction management using sequence of local transactions. A local transaction is the atomic work performed by a saga participant. Each local transaction updates the database and publishes message or event to trigger the next local transaction in the saga. If a local transaction fails Saga will execute a series of compensating transactions to undo the work done for the transaction so far.
Transaction may need to compensate due to varies reasons such as system failures or for example user deciding not make the final payment for his booking. Again compensating the transaction depends on depends on the business use case for example if consider booking a flight and hotel in a single transaction and if flight booking had an issue we can still continue with the hotel booking if required.
Compensating a transaction can be either really deleting the inserted record or adding another transaction with oposit effect to reverse it.
(A pivot transaction is the go no-go point in a saga. If the pivot transaction has been commited it can be compensate therefore.)
Choreography and Orchestration are two common approaches of Saga.
Choreography allows participants to exchange events without a centralized point of control. This doesn’t introduce single point of failure but could be difficult to track where is the event and cyclic dependencies and also integration testing would be hard.
Orchestration approach where centralized controller tells the participants to what and when to execute. This approach avoids cyclic dependencies, clear separation of concerns but has single point of failure.
Things to Consider
This pattern may initially be challenging its requires planning how to implement in a system with multiple services. Also its hard to debug and the complexity grows as participants increases. Must include counter measures to reduce anomalies such as locks.