I’m starting to introduce myself in CQRS concepts, but I get stucked with the following situation:
Supouse you have an entity that must have an unique name. In order to verify that, prior to create the entity you must make a query, thus you are verifing against the query subsystem.
But what happens if the syncronization has not been happened between the command system and the query system yet? Other client just had sent the same name before you.
What happens in that case?
Well, you should not use the query subsystem for validations – use the command subsystem for that. Look into the picture in Fowler’s article here – validations are typically placed at the command model side. If, for example, you try to give an entity a unique name, your command subsystem should throw an exception if that name was already used before. The initiator of that command should expect that this may happen, even when he has used the query subsystem before to find a “free” name.
That is, of course, for the case of “eventual consistency” between those different models, where there is a delay between the synchronisation. If you have a system where both models are strictly kept consistent, rules can be obviously different.
0
There are two possible remedies here.
First is that Race Conditions Don’t Exist. If you are operating at business speeds, where you typically have long running processes, you will typically find that either the races don’t really happen (so you shouldn’t invest too deeply in trying to handle them) OR that the races are allowed, and there are compensating commands that are used to remedy contingencies.
Second approach: if the unique name constraint really is a business invariant that needs to be maintained, then the entity responsible for the creation needs to ensure the uniqueness of the name — for instance, by maintaining a list of all names in use. The client does its best to guard against duplication by checking the read side first to detect if a name is already in use; but in the event of a race by two different clients, one of the commands fails, and the client that loses the race is told of the failure and gets to choose another name.