...
Insert new record to client database through client service;
Insert new record to vessel detail database through vessel detail service;
Insert a new record to vessel registry service through vessel registry service, using the new client Id and new vessel detail Id through vessel registry service, to link the client and vessel details records together via the registration for connecting the first two records to the vessel registry record;
Update the status of the work item to “done”.
Schemas of the services' databases evolve over time, so this assumption may or may not hold, however it should not affect our analysis of the problem as regardless of the order of updates the technical challenges we face will face are still remain the same.
Saga Essentials
When we have a monolith application and insert records in Contacts, Vessel Details and Vessel Registration tables and update Work Items table in its only database, it is simple to make sure that either all 4 tables are updated, or none at all. All we need is to use database transactions. Back to “microservices reality”, where we have all 4 tables living in 4 separate databases and are behind 4 autonomous microservices, we still have to deliver the “all or nothing” behavior, which is so easily achieved in a monolith.
...
This diagram is a way to present the requirement to the saga explicitly. It makes certain assumptions about desired behavior of the system. For example, we assume that the “Adding Registry” state is a pivot state in the saga, meaning that if it succeeds, we are not rolling anything back. In other words, this diagram reflects an assumption that if “Adding Registry” results in success, and subsequent “Updating Work Item” fails, we leave the work item in an inconsistent state, which will need to be manually corrected, but we leaving all three vessel registry records (contact, vessel detail and vessel registration) in a consistent state with each other. An alternative design of this diagram could require rolling back the entire saga from the point when “Updating Work Item” stage fails.
Despite all the measures for enhancing saga resiliency that we talked about earlier, sagas can still fail and lead to data inconsistencies. In the “eventual consistency” concept we started our analysis with the term “eventual” is ambiguous. Is it seconds, minutes or maybe days? If we establish thresholds for how quickly sagas must complete, then we have to account for their potential failures and data corruption it may cause. The likelihood of such failures is low, as it can be thought of as a multiplication of low probability of failure by the low probability of rollback failure, . And so it is not feasible to add additional rollback or retry layers, as it adds complexity. A more rational approach is to invest in being able to pinpoint quickly what specifically is failing, and there is hardly a better strategy than implementing strategic diagnostic logging to achieve this goal.
As the diagram above is an example of a classical finite state machine diagram, the sagas and their states can be modelled modeled using State design pattern. The reason why all states have “pending” connotation is because this approach facilitates making sagas isolatable. Or put another way, it allows handling concurrent requests easier.
Let us now inspect the structure of the orchestrator microservice structure:
...
To be continued…