Does the CQRS project require a messaging infrastructure such as NServiceBus?

The last 6 months of training have been challenging with CQRS and DDD the main culprits.

It was fun, and we reached 1/2 way through our project, and the area in which I did not have time to delve into is the messaging platform.

I currently do not use DTC, so there is a very good chance that if my read model is not updated, I will have inconsistency between the read and write databases. Also, my read and write database will be on the same machine. I doubt that we will ever place them on separate machines.

I do not have a large volume of messages in my system, so my concern is rather related to the consistency and reliability of the system.

So, do I need to embed a messaging framework like NServiceBus (even if the read and write databases are on the same machine) or do I have other options? Yes, there is a learning curve, but I believe that there would be a lot to learn if I do not use it.

In addition, I do not want to put a layer if it is not needed

Thoughts?

+4
source share
2 answers

I currently do not use DTC, so there is a very good chance that if my read model is not updated, then I will have an inconsistency between the read and write databases.

Personally, I don’t like DTC and try to avoid it. Instead, it is often possible to implement a compensation mechanism, especially for something like a reading model, where possible consistency is already acceptable and the updates are idempotent. For example, you can implement a version for entities and have a background job that provides version synchronization. The presence of DTC will provide retransmission functionality, but it still won’t solve cases of failure after retries - you still have to look at the error log and have procedures to resolve the errors.

So, do I need to add a messaging framework such as NServiceBus (even though the databases for reading and writing are on the same machine) or do I have other options?

It depends on a few things. What you often see in the CQRS system is necessary for pub / sub, where several subsystems of the systems publish events to which the request / cache system subscribes. If you see the need for pub / sub besides basic point-to-point messaging, go on to something like NServiceBus. In addition, I would not immediately shy away from using NServiceBus, even if you do not need it for scalability purposes, because I think logical partitioning is useful for myself. On the other hand, as you point out, adding layers of complexity is expensive, so first try to see if the simplest possible thing will work.

One more question: do you need a separate query store at all. If all you have is one machine, why bother? You could use something simpler as a model model model , and still reap the many benefits of CQRS.

+6
source

Does the CQRS project need a messaging infrastructure such as NServiceBus?

The short answer is no.

This is the first time I hear about the “model reading model” mentioned by eulerfx. This is a pretty nice name, but there is something else:

The basic idea behind the query part is to request a denormalized view of your data. In the "read-model" link, you will notice that the query used to populate the read model does some lifting. In the given example, the required data manipulations are not so complicated, but what if they become more complex? This is where denomination begins. When you execute your “command” part, the next step is to denormalize the data and save the results for readability. All hard work must be done by your domain.

That is why you are asking about messaging. There are several methods here:

  • denormalized data in the same database, the same table, different columns
  • denormalized data in one database in another table
  • denormalized data in another database

This is the repository. How about consistency?

  • immediately matches
  • finally consistent

The simplest solution (quick win) is to denormalize your data in your domain, and then, after saving the objects of your domain through the repository, you immediately save the denomalized data in the same data store, the same table (s), different columns. At 100%, and you can immediately start reading denormalized data.

If you really want to, you can create a separate group of objects to transport this data, but it's easier to just write a simple query layer that returns some data transfer object provided by your data access structure (in the case of .Net, it should be DataRow / DataTable ). There is absolutely no reason for imagination. There will always be exceptions, but then you can go ahead and write a data container.

For possible consistency, you will need some form of queue and related processing. You can turn your own decision or you can choose a service bus. It is up to you and your time / technical limitations :)

By the way, I have a free open source service bus here:

Any feedback would be welcome. But any old service bus (MassTransit / NServiceBus / etc.) will do.

Hope this helps.

+5
source

Source: https://habr.com/ru/post/1439623/


All Articles