Transactional Outbox & Polling Publisher Patterns (2/3)
Over time, NoSQL databases have improved their features to offer us ACID according to the type (Single Row, Single Shard or Distributed):

The main problem is not whether a certain database guarantees ACID or not in its transactions (logically, it should to minimize the risk of inconsistencies), but dividing the operations of the same workflow (complete creation of the order with all its operations) into several independent local transactions between the different contexts and databases, whatever they may be.
So guaranteeing communications between contexts is vital to allow distributed executions between them while maintaining data consistency.
Normally we must notify the event once the local transaction is completed. To do this, we execute the transaction and then publish the event to our message-broker:

The problem is that the transaction and the sending of the event are not atomic: they are executed independently, which can cause possible data inconsistencies if either fails:


The Transactional Outbox pattern will allow us a single atomic transaction guaranteeing an At-Least-Once delivery and giving us the possibility to reprocess them at any time.
We will apply it by saving in the same transaction both the operation we want to perform (which guarantees ACID), and the events it may generate. The events will be persisted in the database:

Through Polling Publisher we would publish the events to our message-broker. Maintaining the status of the events in the outbox checking the ACK at the time of publication (thus ensuring the reception of the event). Or even, the consumer could update the event to processed correctly using a CorrelationId or MessageId.
We will ensure At-least-once/Once-or-more (messages will not be lost, although they could be duplicated). For that reason, our consumers should be idempotent (the execution of one or more times will have the same result).
There are interesting tools already developed that will allow us to adapt the outbox pattern easily:
As I mentioned, there are distributed database engines that allow us data consistency in their transactions (with certain performance penalties):
Azure Cosmos Db gives us the option of strong consistency (single region/single operation) and guaranteeing ACID through TransactionalBatch. Offering us the Change Feed Functions in which it will notify us of any insertion or update of a specific container. For this, we will need a collection where we will save the processed state of the notifications (lease containers).
In this way (with some nuances) we can approach the outbox pattern easily (although, ideally we should create a specific collection of events generated and have a polling publisher):

To avoid this performance penalty and guarantee consistency: we could listen to the events generated creating the specific query data in some other database or technology. Also notifying other services (given the importance in the consistency of data in distributed business transactions as we will see in the next post):

So far one of the most commonly recommended patterns to guarantee the sending of events corresponding to local transactions of each service.
Recommended readings:
- https://leadingdepth.com/saga-pattern-3-3/
- https://docs.microsoft.com/en-us/dotnet/architecture/microservices/multi-container-microservice-net-applications/subscribe-events
- https://docs.microsoft.com/bs-latn-ba/azure/cosmos-db/how-to-create-multiple-cosmos-db-triggers
- https://docs.microsoft.com/es-es/azure/cosmos-db/consistency-levels
- https://microservices.io/patterns/data/transactional-outbox.html
- https://jimmybogard.com/life-beyond-distributed-transactions-an-apostates-implementation-relational-resources/
- https://www.kamilgrzybek.com/design/the-outbox-pattern/