Dual write is a problem when we need to change data in 2 systems: a database (SQL or NoSQL) and Apache Kafka (for example). The database has to be updated and messages published reliably/atomically. Eventual consistency is acceptable but inconsistency is not.
Without 2 phase commit (2PC) dual write leads to inconsistency.
But in most cases 2PC is not an option.
Transactional Outbox is a microservice architecture pattern where a separate Message Relay process publishes the events inserted into database to a message broker.
Multiple Message Relay processes running in parallel lead to publishing duplicates (2 processes read the same records in the OUTBOX table) or unordering (if every process reads only portion of the OUTBOX table).
A single Message Relay process might publish messages more than once also. A Message Relay might crash after processing an OUTBOX record but before recording the fact that it has done so. When Message Relay restarts, it will then publish the same message again.
How to implement a Message Relay in Transactional Outbox patterns, so that risk of duplicate messages or unordering is minimal and the concept works with all SQL and NoSQL databases?