Command Query Separation validating for retries
So I'm comfortable with the basic concept of CQS, where you might have a command that writes to one database, and that updates the query database that you read from.
However, consider the scenario where you are entering data, and want to prevent duplicates.
Using new employee data entry an employee register as an example, working through a pile of application forms to key in the new employees' details:
- Take top sheet.
- Key in employee name and unique payroll number to UI.
- Submit.
- Put paper in "completed pile".
- Repeat.
How would you now prevent the u开发者_开发技巧ser from keying in the same payroll number again, say for instance if they get distracted and can't remember whether they've keyed one in already and the "message" hasn't got all the way back to the query db for the user to search?
First off you can easily use a local cache to make sure the immediate user does not re-use the same numbers again. That's easy enough.
But really this doesn't stop the fact that by mistake two people can use the same critical piece of data at the same time. As someone else mentioned though this is outside of CQRS. This could happen in almost any architecture.
Now the main thing that CQRS could change is how we respond to a conflict. I see two possible solutions:
The system sends the command off and then waits for a successful result. If it's a failure you just ask for fixed information and try again. From everything I've heard this seems wrong and might even be an anti-pattern though I'm no where near expert enough to say either way.
The system sends the command off and eventually the user is informed about the conflict. There is somewhere they can go to fix the problem. In your case by entering a new number (which could again conflict).
Data entry is a non-collaborative domain - you don't have multiple users performing actions on the same shared set of data. As such, CQRS isn't particularly relevant.
I suggest to change the workflow to this
- Check the top sheet is taken or not in database (you should have a table R to remember whether the specific row is taken or not), if taken then return false if not, then Take top sheet. and set the flag for the taken row to be "taken" in table R
- Key in employee name and unique payroll number to UI.
- Submit.
- Put paper in "completed pile".
- Repeat.
The step should be execute atomically.
Could you keep track of a list of already entered employee/payroll number combos on the client? If this is a web client, could be a cookie, if a thick client, then memory or otherwise. When they enter the system for the first time, clear the list and start anew.
精彩评论