Problem
We
have talked about one database per service being ideal for microservices, but
that is possible when the application is greenfield and to be developed with
DDD. But if the application is a monolith and trying to break into
microservices, denormalization is not that easy. What is the suitable
architecture in that case?
Solution
A
shared database per service is not ideal, but that is the working solution for
the above scenario. Most people consider this an anti-pattern for
microservices, but for brownfield applications, this is a good start to break
the application into smaller logical pieces. This should not be applied for
greenfield applications. In this pattern, one database can be aligned with more
than one microservice, but it has to be restricted to 2-3 maximum, otherwise
scaling, autonomy, and independence will be challenging to execute.
Shared Database per Service
Use a (single) database that is shared
by multiple services. Each service freely accesses data owned by other services
using local ACID transactions.
Example
The OrderService and CustomerService freely
access each other’s tables. For example, the OrderService can use the
following ACID transaction ensure that a new order will not violate the
customer’s credit limit.
BEGIN TRANSACTION
…
SELECT ORDER_TOTAL
FROM ORDERS WHERE
CUSTOMER_ID = ?
…
SELECT CREDIT_LIMIT
FROM CUSTOMERS WHERE CUSTOMER_ID = ?
…
INSERT INTO ORDERS …
…
COMMIT TRANSACTION
The database will guarantee that the credit limit will not be
exceeded even when simultaneous transactions attempt to create orders for the
same customer.
The benefits of this
pattern are:
·
A developer uses familiar and straightforward ACID transactions
to enforce data consistency
·
A single database is simpler to operate.
The drawbacks of this
pattern are:
· Development time
coupling
- a developer working on, for example, the OrderService will need to
coordinate schema changes with the developers of other services that access the
same tables. This coupling and additional coordination will slow down
development.
· Runtime coupling - because all
services access the same database they can potentially interfere with one
another. For example, if long running CustomerService transaction
holds a lock on the ORDER table then the OrderService will
be blocked.
· Single database might not satisfy the data storage and access
requirements of all services.
Nice one
ReplyDeleteThank you