Transactional outbox
Write the event in the same database transaction as the change, then publish it from there, so the database and the broker never disagree.
The transactional outbox makes "save the order and announce it" one atomic step.
Use it when#
A change in your database must also produce a message, such as
OrderPlaced.Losing the message or sending a message for a rolled-back change would corrupt another service.
How it works#
The naive code saves the row, then publishes to the broker. If the process dies between the two, the row exists and no one hears about it. Swap the order and a failed save leaves a message about nothing. The two systems cannot share one transaction.
So the app inserts the event into an outbox table inside the same transaction as the order. A relay process reads new outbox rows and publishes them, then marks them sent. A crash after publishing and before marking sends the event twice, so consumers must handle duplicates.
What it costs#
Events arrive a little later than the commit, because the relay polls or tails the log. You run and watch one more process, and the outbox table needs cleanup. Delivery is at-least-once, so idempotent consumers are required.
In Quorum#
Drag to pan. Hold Ctrl or Cmd and scroll to zoom.
| Where | Setting | Value | Why |
|---|---|---|---|
| App Server | Instance size | medium | Medium, so the App Server is not the limit. |
| Database | Instance size | medium | Medium. It holds the rows and the outbox. |
| Realtime Hub | Stack | node | An event loop holds each open connection for a few KB, where the default Stack holds a worker for each. |
| Realtime Hub | Clustering | On | Without it one box takes every connection. |
Research this Design needs: Full-text search, Checkout, Hosted models, WebSockets, Object storage, WebSockets, Message queues, Full-text search, Transactional outbox.
The other Nodes in the picture only serve the other request kinds of Series B, such as checkouts and realtime. Research Transactional outbox and the game stops counting the dual-write loss: from Series B, a share of search answers is stale when the app writes to the Database and the Search Engine separately and nothing carries the change. The outbox is a Research, not a Node, so the Design shows only its effect and has no setting of its own. A CDC Connector removes the same loss by reading the Database log, which Change data capture covers. The glossary defines the transactional outbox.