Joint table ownership in microservices occurs when multiple services perform write operations on the same table.

Right off the bat, I’ll make it clear that no one likes joint ownership of tables.

A few reasons for this are:

  • Increased coupling between the services
  • Bigger impact of changes to the shared table
  • The need for more testing

However, it’s not always possible to avoid joint table ownership as we saw in the previous post about Data Ownership in a Distributed System.

You can check out that post for more context. But to explain things in brief, here’s what joint table ownership looks like:

joint ownership microservices

The BookCatalog service maintains the data (including inventory levels) about each and every book in the library.

However, due to its wider scope, both the BookCatalog service and the BookInventory service need to perform write operations on the Catalog table.

Any changes to the BookCatalog table impacts both services. Not an ideal situation by any means.

So – how can we deal with this situation?

Let’s discuss a few techniques to address the joint table ownership situation:

1 – The Table Split Technique

The simplest way to deal with joint table ownership is to get rid of the joint tables.

This means splitting the BookCatalog table into two separate tables – the BookCatalog and the BookInventory.

Basically, we are converting joint ownership into single ownership and making each service own the part of the data that it’s responsible for.

Here’s what it looks like:

table split joint microservices

This sounds great!

Problem solved, I suppose.

Not so fast.

While we have now solved the joint ownership situation, the table split creates several new problems of its own.

  • Firstly, this arrangement requires communication between the BookCatalog service and the BookInventory service to maintain consistency between the two tables.
  • If a new product is added, the BookCatalog service generates a book id and inserts it into the Catalog table. It also needs to send the new book id to the BookInventory service so that the data can be updated in the BookInventory table.
  • In case a product is removed, the BookCatalog service first needs to remove the book from the BookInventory table via the BookInventory service.

This synchronization process isn’t trivial by any means.

Some hard questions you’ve to answer are as follows:

  • Should the communication between the BookCatalog service and the BookInventory service be synchronous or asynchronous?
  • What should the BookCatalog service do if the BookInventory service is down for some reason?
  • Should the BookCatalog service go for availability or consistency?

In other words, there are many trade-offs to consider when choosing the Table Split technique.

2 – Delegate Technique

This is my personal favorite technique of addressing the joint table ownership scenario.

In this technique, one service is assigned the single ownership of the table. In other words, this service becomes the delegate and the other service communicates with the delegate to perform updates on the table.

The problem is determining which service to assign as the delegate (or sole owner of the table).

There are two ways of doing so:

Based on Domain Priority

In this option, we assign table ownership to the service that most closely represents the primary domain of the data.

What does it mean?

Basically, the service that does most of the CRUD operations for the particular entity within the domain.

In our example, the BookCatalog service performs most of the CRUD operations on the BookCatalog entity.

Hence, the BookCatalog service becomes the single owner of the table. The BookInventory service must go through the BookCatalog service to retrieve or update inventory information.

See the below illustration:

table ownership delegation based on domain priority

Based on Operational Needs

Though I prefer the domain-based delegation, there’s another way of determining the delegate.

It’s based on operational needs.

For example, in our scenario, updates to the book inventory take place at a much faster rate than updating static book information.

In other words, the BookInventory service needs to deal with the BookCatalog table far more frequently on a real-time transactional basis. The administrative task of updating the actual book details happens rarely.

With this consideration, the roles can be reversed. The BookInventory service becomes the owner of the BookCatalog table.

See the below illustration.

table ownership delegation based on operational needs

Of course, the main problem is that this approach completely breaks up the domain management responsibility.

The BookInventory service becomes responsible for creating, updating, and deleting book records.

This makes things a lot more messy in the grand scheme of things.

3 – Service Consolidation

A third approach to deal with joint table ownership between multiple services is the Service Consolidation Technique.

This technique deals with joint ownership by combining multiple table owners into a single consolidated service.

Check out the below illustration:

service consolidation for table ownership

While this approach converts the joint ownership problem into a single ownership situation, it creates a few problems of its own:

  • We end up with a more coarse-grained service.
  • Increases the scope of testing
  • Higher deployment risk
  • Reduced fault tolerance since all parts of the service fail together
  • Scaling becomes a problem because you need to scale all parts of the service together even when it might not be required.

Conclusion

Joint table ownership between multiple microservices is an undesirable situation for the system.

If you encounter such a situation, it’s important to find alternatives that make your system more robust.

There are multiple techniques such as splitting the table, delegation and service consolidation to convert the joint ownership into a single ownership scenario where things become easier to manage.

Ultimately, each technique has a bunch of trade-offs that need to be considered while choosing the optimal approach.

If you enjoyed this post, share it with your friends or colleagues.

Also, consider subscribing to my free newsletter where I deliver practical software design tips straight to your mailbox.


Saurabh Dashora

Saurabh is a Software Architect with over 12 years of experience. He has worked on large-scale distributed systems across various domains and organizations. He is also a passionate Technical Writer and loves sharing knowledge in the community.

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *