7

I am reading this article about CQRS, and when it comes to decide where to use it, the following didn’t really get to my mind:

Collaborative domains where multiple operations are performed in parallel on the same data. CQRS allows you to define commands with enough granularity to minimize merge conflicts at the domain level (any conflicts that do arise can be merged by the command), even when updating what appears to be the same type of data.

Can some elaborate it with possibly some example. I think what it means is that you can issue more granular write commands to update smaller parts of a table, row, etc. to minimize overlapping hence, locking on smaller areas so better performance. But how is that not possible with everyday CRUD operations?

  • 1
    As is often the case with Microsoft's way of explaining DDD/CQRS, I'm not sure why they included command conflict resolution as a core benefit of the pattern, let alone as #1 in the list. To my knowledge, the concept of "merge conflict" doesn't appear elsewhere in CQRS literature. Sure, you can manage concurrent commands this precisely if needed in your context, but you don't have to. I see this benefit as a nice byproduct of having neatly defined commands, not as a central reason/concept. – guillaume31 Jan 29 '18 at 12:43
  • 1
    What's even stranger is that they refer to the Aggregate pattern multiple times, without having a proper entry for it. Now the typical countermeasure in DDD+CQRS when high concurrency problems come up is to change aggregate design, more than try and merge incoming commands. Maybe they have their own, different interpretation of Aggregate. – guillaume31 Jan 29 '18 at 12:51
4

Yes, you can have granular commands with CRUD also. That paragraph is not about the differences between CRUD and CQRS, but where you could use CQRS.

In order to understand the differences you should read the entire article, maybe more than once.

Regarding the commands, one difference between the two architectures is that, in CQRS the command has also a meaning from the business point of view, it carries also the intent, by having a name from the Ubiquitous language. In CRUD the intent, the why is missing; it could be derived from what fields are modified but it is obscured.

  • But what exactly the merge conflict is here? – Tarik Jan 28 '18 at 14:44
  • Merge conflict is when two commands are sent at the same time to the same entity. – Constantin Galbenu Jan 28 '18 at 14:55
3

I like Udi Dahan's post about CQRS the most, and I take an example from there:

Let’s say we have a customer service representative who is one the phone with a customer. This user is looking at the customer’s details on the screen and wants to make them a ‘preferred’ customer, as well as modifying their address, changing their title from Ms to Mrs, changing their last name, and indicating that they’re now married. What the user doesn’t know is that after opening the screen, an event arrived from the billing department indicating that this same customer doesn’t pay their bills – they’re delinquent. At this point, our user submits their changes.

Should we accept their changes?

Well, we should accept some of them, but not the change to ‘preferred’, since the customer is delinquent.

And, concerning your question

But how is that not possible with everyday CRUD operations?

There is no such thing as command in CRUD by definition. In CRUD we have only, um, CRUD: create, read, update and delete. So that's how command imitation with CRUD looks like (again, it's an excerpt from Udi Dahan's post):

But writing those kinds of checks is a pain – we need to do a diff on the data, infer what the changes mean, which ones are related to each other (name change, title change) and which are separate, identify which data to check against – not just compared to the data the user retrieved, but compared to the current state in the database, and then reject or accept.

It's not only about performance. It's also about enhancing overall user experience. If the command is valid, that is, date ranges, emails, etc (which can be ensured on the client side), server does not have to return any errors most of the time. It can handle any inconsistencies caused by parallel commands asynchronously, and notifying a client with, say, an email. This became possible, as Constantin Galbenu also said, because commands capture a business intent. In case of any "race condition" you can ask your domain expert what to do and he'll be able to answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.