Before we deploy the Product service, we need to look at how we migrated the data from the monolith representation to our microservice model. As we did with the Order service, we must consider how the Product service will want to represent its data in a multi-tenant model. This means thinking about performance, isolation, and so on. We decided that, for products, we’d demonstrate another flavor of data partitioning, using a “pooled“ model where the data for tenants would co-exist in the same tables of a relational database (isolated by a column with a tenant identifier). This means that our service will use the same database for all tenants and won’t require us to provision new tables or other constructs as new tenants are introduced.
In many respects, the code for interacting with the multi-tenant database does not change that much from the silo version (since they were both working against a relational database and the schema is mostly unchanged). Let’s look at a snipped code that illustrates the minor tweaks that are needed to move from our monolith database to our pooled, multi-tenant representation.
private final static String SELECT_PRODUCT_SQL = "SELECT p.product_id, p.sku, p.product, “ + p.price, c.category_id, c.category " + "FROM product p LEFT OUTER JOIN ( " + "SELECT x.product_id, MAX(x.category_id) AS category_id " + "FROM product_categories x INNER JOIN product y ON x.product_id = y.product_id " + "GROUP BY x.product_id) AS pc " + "ON p.product_id = pc.product_id " + "LEFT OUTER JOIN category AS c ON pc.category_id = c.category_id " + "WHERE tenant_id = ?”;
This code represents the string that is used for our SQL statement to query the database for products. It mirrors what was in our single-tenant monolith. However, one last piece was added at the end. The “WHERE tenant_id = ?“ reflects that we’ve added an “tenant_id“ column to our relational database and will use it to shard the data for each tenant.