Inside a microservice architecture, consider a service A
which receives a request from an user and persist some data in to its database.
Once persisted, service A
has to notify service B
. This notification action to service B
can happen asynchronously(not needed immediately).
A few ways to implement the above requirement could be:
service A
persist(insert + commit) data in to DBservice B
to consumeservice A
persist(insert + commit) data in to DBservice B
is a subscriber to a topic in KAFKA and fetches the messageIn a microservice architecture like the one you're describing, the primary goal is to ensure that Service A can reliably and efficiently notify Service B once it has persisted data. Let's break down the two approaches you've mentioned and then discuss the dual-write problem and additional alternatives.
Approach #1: Queue System
Pros:
Cons:
If Service A successfully writes to the database but fails to send the message to the queue (or if the message gets lost in the queue), Service B won't be notified.
Ensuring the data is in sync between the two services can be challenging.
Approach #2: Transaction Outbox with CDC and Kafka
Service A persists data in its database (insert + commit).
Transaction outbox pattern is used, where an "outbox" table in the database is updated as part of the same transaction.
Change Data Capture (CDC) picks up changes in the outbox table and pushes them to Kafka.
Service B subscribes to a Kafka topic and fetches the message when it appears.
Pros:
Cons:
The dual write problem is significant because it affects data consistency and system reliability. If one write succeeds (to the database) but the other fails (to the queue or outbox), the systems can become out of sync. The severity depends on how critical it is for Service B to receive all notifications without loss or delay. In systems where consistency isn't as critical, or where occasional manual intervention is acceptable, the dual-write problem might be less of a concern.
Additional Approaches
Approach #1 might be sufficient for systems where eventual consistency is acceptable or where the volume and criticality of the messages don't justify the added complexity of Approach #2. However, for systems requiring strong consistency and reliability, investing in more robust solutions like Approach #2 or exploring additional approaches might be necessary. Consider the trade-offs in terms of development and operational complexity, performance, and reliability to choose the right approach for your needs.