0

We have 2 microservices:

service_A, service_B. Both of them use the same database. Today I find out that we have repositories for the same tables used by the different services. I remember that I read that it is a design mistake for some reason and tried to google that information. But unfortunately my search was not successful. Could you please explain that problem?

Also it might be my mistake. So is it ok to use the same table for different microservices?

gstackoverflow
  • 36,709
  • 117
  • 359
  • 710
  • Btw it's not really a microservice if each microservice doesn't own it's data and use same database – vanillaSugar Oct 15 '18 at 10:33
  • Its a design pattern, as such you can do anything - so long as you don't mess up. Here are some articles about both [Shared database](https://microservices.io/patterns/data/shared-database.html) [Per service database](https://microservices.io/patterns/data/database-per-service.html) – Worthless Oct 15 '18 at 10:34
  • Having a common DB makes it lose its independent nature. – Shivam Aggarwal Oct 15 '18 at 10:35
  • An useful link on the topic i think : [link](https://stackoverflow.com/questions/3479297/multiple-application-using-one-database) – dbl Oct 15 '18 at 10:36
  • 1
    Possible duplicate of [Microservices with shared database? using multiple ORM's?](https://stackoverflow.com/questions/43612866/microservices-with-shared-database-using-multiple-orms) – Constantin Galbenu Oct 15 '18 at 10:37
  • I think its a pretty big misconception that microservices -> no shared database. You can share the database but its just tighter coupling. If the schema doesn't evolve as much between the databases, it is often a non-problem. Same concept when it comes to refactoring, refactor parts that gives you and your team the highest contention. Don't focus on refactoring just to make it prettier :). – Will C Oct 16 '18 at 16:45

1 Answers1

3

From my experience, it's not a good practice to share the same data between microservices. Here is the (probably incomplete) set of reasons:

  • It's hard to tell which microservice is really the data owner. This is not good from the architectural stand-point

  • A cost of schema change is much higher because the contract is not well defined. For example, if you remove, say, column, in one microservice, the second microservice can stop working, even if the code of the first microservice has been adjusted for changes. In other cases, it will still work but the performance may aggravate (like removing an index by a maintainer of the first microservice, because it's not relevant for queries done in it, can cause performance aggravation of the second microservice)

  • If some microservice has a caching of some data and can hold data in-sync between the different instances of the same microservices, it can be tricky to keep proper synchronization if another microservice updates the database directly and doesn't notify the first microservice about the changes.

  • If a database is a performance bottleneck, both microservices will be influenced, especially its hard to handle, if these microservices have different scalability policies

  • A cost of migration to the different database (if required) will be much higher because the code must be changed in both microservices

  • If using an ORM, such as JOOQ (any tool that requires code generation), it's not really easy to understand where to put generated files? In both microservices? In one of them? How to share the Data Model

  • Metrics that are usually built per microservices will be tricky because if we measure an access to some table in DB, we're not sure that another microservice won't access that table as well.

Now, having said all that, after all its a recommendation to not use this practice, technically there is no reason why it won't work. So the decision is yours after all. I can say from a personal experience, that in one of my projects we stopped managing shared database between microservices and it was a step in a right direction from my standpoint.

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97
  • About the third bullet, I think this becomes a problem either way. By moving to microservices, you have opted for eventual consistency rather than transactional. If you had separate databases, the latency in the message being propagated would be how long it would be stale for. As for caching, that also depends on a satisfactory TTL and how likely, it'll be updated. Other than that, I think you made some good points about shared databases aren't great. – Will C Oct 16 '18 at 16:44
  • Thanks, Will C. I meant a different case in mind. Say Microservice that owns the data, also pre-caches it in, say, Redis. So the "reads" check whether the data is in redis, and if the data is not there go to the database. If the data has been updated (again by the same microservice), cache invalidation message is broadcasted. Now, if the data is shared, its possible that another microservice will update the data but won't notify (how does it know that someone else pre-caches the data). So the data consistency will be flawed big time. – Mark Bramnik Oct 16 '18 at 17:57
  • Agreed, it really depends on the cache invalidation scheme which in some cases could be more difficult than it seems initially eg. TTL, LRU, data size, etc for that matter. In my opinion, data should never be held indefinitely in the cache anyway. – Will C Oct 16 '18 at 18:02
  • Yes, sure, you're right, an invalidation should be done after some TTL, LRU or whatever in any case, the invalidation, however, is kind of out of scope for this question, so I just tried to bring use cases where data sharing might harm out of my head :) – Mark Bramnik Oct 16 '18 at 18:07