3
votes

I have to design a system of clients connecting to WCF service(s) to perform read and write operations on a database, and also get notifications.

I was told to use CQRS pattern.

For the sake of an example, clients will connect to a service to perform operations like Get List Of Products and Update Product. They will also be able to do something like Accept Shipment and Reject Shipment (which might cause a race between clients who is the one to do it first). Only one client can 'accept' a shipment or 'reject' a shipment.

So I read a little bit about CQRS and understood it decouples the reads from the writes (using commands). However, I am not sure about a few major issues if I use CQRS :

  1. If I use CQRS pattern on the WCF service - can I count on things being done synchronously on the database ? I am a bit confused, cause I don't want the service to be single threaded (to support future scalability), but on the other hand - how do I make sure that write operations on the service are performed in the right order ? or even read operations ? Does the CQRS pattern guarantee ordered processing ? (someone told me here that CQRS pattern uses an 'update' queue to update requests for offline processing).

  2. Does using CQRS eliminate concurrency problems ?

  3. Should I still use 'TransactionScope' in all my command handlers that interact with the database ?

  4. I have spent more than a week in trying to understand how to implement the notifications service for the clients, with no luck. I have this design: design

'Product Service' will be a CQRS service, but I have trouble with the notifications service. The client may send a command to the product service to be notified about products of category X. This command will update the request in the database. Let's say for now that the notification service polls the database every 15 minutes, and checks which user wanted to be polled on which category and then sends new products to users that requested to be notified on those product's categories. What happens now if a user changes a category for a product and 20 other users already see this product in their notification window ? I need some way to detect that the product is no longer of that category, and to send them a notification like 'remove that product from your view'. This doesn't sound so much like notifications. It sounds more like 'Request a CONSTANT RELEVANT view of a database table, and every change should be reflected to the client's screen'. How do I do this kind notification service ??

2

2 Answers

2
votes

This may not be an answer to your specific questions, but might be helpful in evaluating if, why, and in what parts of yor application you can (or maybe should) use CQRS at all?

More specifically: CQRS is neither a silver bullet that should be applied no matter what, nor is it an overarching architecture style across the whole of your application.

CQRS can provide many advantages when applied to single and well specified Bounded Contexts (see Domain Driven Design by Eric Evans).

Questions you or your team should ask first:

  • What are the Bounded Contexts of my application?
  • For each BC: Is it basically CRUD or does it need more complex and sophisticated modelling?
  • if it's CRUD then implement it as such
  • if it's complex then has the problem been solved already? Is there a need to reinvent the wheel or can we just use a finished solution (conceptually or even a piece of software)
  • if we need to build it ourselves, does this specific BC provide the main business value and does our implementation provide the potential of for instance a competitive advantage? (refer to the "Core Domain" in Domain Driven Design)
  • if the above applies then research various architecture styles and choose the best fit.

Long story short: Don't try to force a style upon your whole application. Identify BCs and for each use the simplest solution that meets the requirements. This can very well be CQRS but for one or two BCs within your application at most.

Concentrate the effort on the parts of your application that are most complex and provide a real advantage if formalized and implemented using CQRS.

0
votes
  1. Databases don't do things synchronously, they use transactions which are interleaved according to the rules of database transaction isolation levels. But they do update their indices as a part of the transaction, and that's the part that matters.
  2. No it doesn't but it eliminates the problem of a single writer blocking multiple readers where you have highly contended resources, such as database tables. E.g. in a system I worked on, blast data was being inserted from sensors and also read as a part of creating a report for users. This is a location where CQRS fits well. Most implementations of CQRS have their concurrency issues under control, and it's actually a nice model together with DDD, where your concurrency is heavily contended business logic. You get other properties, however, like not having a stack or having to dead with idempotence and message re-ordering.
  3. You'll have two databases; one that saves events (if you are doing event sourcing)/entities and another/multiple others per view that you want to keep up to date with events.
  4. You'd want to use something like MassTransit + SignalR. Create a read model (basically a DTO per screen) that subscribes to events and pushes notifications to the browser through a SignalR-hub.