0

According to my understanding

  • We should only have one service connecting to a database
  • With CQRS you will be keeping two databases in sync, hypothetically using some “service” glueing them together

Doesn’t that now mean there’s a service which only purpose is to keep the two in sync, and another service to access the data.

Questions

  1. Doesn’t that go against rule number above? Or does this pattern only apply when native replication is being used?
  2. Also, other than being able to independently scale the replicated database for more frequent reads, does the process of keeping both in sync kind of take away from that? Either way we’re writing the same data to both in the end.

Ty!

Levi Ramsey
  • 18,884
  • 1
  • 16
  • 30
rubixibuc
  • 7,111
  • 18
  • 59
  • 98

1 Answers1

2

We should only have one service connecting to a database I would rephrase this to: each service should be accessible via that service's api. And all internals, like database, should be completely hidden. Hence, there should be no (logical) database sharing between services.

With CQRS you will be keeping two databases in sync, hypothetically using some “service” glueing them together

CQRS is a pattern for splitting how a service talks to a data layer. Typical example would be something like separating reads and writes; as those are fundamentally different. E.g. you do rights as commands via a queue and reads as exports via some stream.

CQRS is just an access pattern, using it (or not using it) does nothing for synchronization. If you do need a service to keep two other ones in sync, then you still should use services' api's instead of going into the data layer directly. And CQRS could be under those api's to optimize data processing.

The text from above might address your first question. As for the second one: keeping database incapsulated to a service does allow that database (and service) to be scaled as needed. So if you are using replication for reads, that would be a reasonable solutions (assuming you address async vs sync replication).

As for "writing data on both ends", I am actually confused what does that mean...

AndrewR
  • 1,252
  • 8
  • 7
  • I'm trying to understand the rules and exceptions to those rules for having one service per database with microservices. According to what you just wrote, it seems like it should always be one service both doing the reads and write to a single database. So if there is some sort of consumer reading data from a stream, it should write records using that single service, is that what you're kinda saying? Also I don't understand the last part you wrote, don't we want to only have one service accessing a db? I don't understand what you meant about scaling and how async/sync relates to that – rubixibuc Dec 18 '22 at 01:13
  • In the case of CQRS if there is one service per database, than the synchronization service would read from service A and write to service B correct? Not read or write from db directly? – rubixibuc Dec 18 '22 at 01:14
  • you could model your system with a service holding the data and exposing api for those. E.g. inserUser(username) and exportAllUsersAsFile() - and these api's will be widely different, one is an insert and the other could be an async job. That would be the CQRS example. I always recommend to model services so each would own a business function - not just database. E.g. you would have a UserService for api's from above. If you want to have stuff in sync - SyncService seems like a reasonable thing - it will be responsible for sharing the data. Do you have a specific system you are modelling? – AndrewR Dec 18 '22 at 04:23
  • If you have a resource heavy writer and a low resource reader for instance, would it still be an anti pattern to have two services to talk to the same db? – rubixibuc Dec 19 '22 at 02:30
  • I would share database :) https://docs.aws.amazon.com/prescriptive-guidance/latest/modernization-data-persistence/shared-database.html - I really don't like this, but this seems to be a valid trade off on many cases. At the end of the day, your users should be happy and having some coupling may be acceptable. – AndrewR Dec 19 '22 at 03:14
  • I have a second thought: if a service is write heavy, clearly that would be the reason for scaling out. In many cases, if I have low intensity read API's on the same service, then those read will be scaled automatically. E.g. a service with getKey(K) and setKey(K, V) - even if it is write heavy, I would consider keeping both apis in the same service. – AndrewR Dec 19 '22 at 03:45