Using CQRS and Event store the choreography between microservices delivers an Eventual consistency where in the changes in one microservice take a bit to propagate to the other downstream systems(essentially other microservices) which are related. What are the options if the data is so critical that both the microservices should have a strong consistency for the data? One option that i can think of is a write through Cache like a data grid but that would be very fragile specially in a distributed system.
Whereas eventual consistency is only a liveness guarantee (updates will be observed eventually), strong eventual consistency (SEC) adds the safety guarantee that any two nodes that have received the same (unordered) set of updates will be in the same state.
Eventual consistency is a concept brought by CQRS (most of the times).
For transactions, use patterns such as Scheduler Agent Supervisor and Compensating Transaction to keep data consistent across several services. You may need to store an additional piece of data that captures the state of a unit of work that spans multiple services, to avoid partial failure among multiple services.
Strong consystency is hard in distributed services and even harder with microservices because they own their data. This means that you can have strong consystency only inside a microservice.
However, you could model the critical operations as a complex process using a Saga/Process manager. This means that you use a Saga to orchestrate the completion of the operation in a manner that is acceptable by your business. For example you could use something like the Reservation pattern
This pattern enables managing the resource allocation process in an orderly manner by implementing a two pass protocol - somewhat similar to a two phase commit. During the first pass, the initiator asks each participant to reserve itself. If the initiator gets an OK from all the involved services - within a timeout - it will start the second pass, confirming reservation to all the participants.
In such scenario, think about C.A.P. Theorem. According to Wikipedia, "the CAP theorem states that in the presence of a network partition, one has to choose between consistency and availability. Note that consistency, as defined in the CAP theorem, is quite different from the consistency guaranteed in ACID database transactions."
Since you have 2 microservices, so your system definitely needs to be partition tolerant and you are left with either A (Availability) or C (Consistency). If you want to go with C, then your system will suffer in availability terms. When a request comes into Microservice A, then you should not send back a success message to the client until A gets back a response from Microservice B that data has been successfully stored. This way you can achieve consistency by sacrificing availability.
in this case whenever any activity start on Account it can fetch the current state from Interest microservice, this way you will always be in sync but you will be making service dependent on each other such that when Interest Service Down , Account service will be effectively down.
Looking down your question, i think what you need to think about is whether consistency is so so important(i am posing this question as when coming from a monolith or transaction background we tent to think that consistency is there).
For eg: lets say if you are placing a Order on amazon and you need to send a customer id , there is a case where you should check whether customer id is valid or not.
this will make Order Service dependent on Customer Service.
Another solution of this would be while placing a order do not check customer id , but check it on OrderPlace event and take necessary action.
So try to make sure the system better responds to eventualness of state rather than focusing on transaction in microservice. But if yes there are needs which is very very critical to business then make them dependent
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With