Transactional outbox

트랜잭셔널 아웃박스

Write the database change and pending event in one transaction.

···
html
<div class="scene"><div class="title">ONE COMMIT, THEN PUBLISH</div><div class="transaction"><div id="orderRow" class="tile">ORDER ROW</div><span>+</span><div id="outboxRow" class="tile">OUTBOX ROW</div></div><div class="row publish"><div class="tile" id="commit">COMMIT</div><span>→</span><div class="tile" id="broker">BROKER</div></div><div class="muted" id="outboxState">Both rows are committed together</div></div>
css
.scene{width:min(94vw,760px);height:min(86vh,320px);padding:clamp(10px,2.5vmin,18px);border:1px solid var(--line);border-radius:14px;background:var(--surface);color:var(--fg);font:500 clamp(11px,1.3vw,16px)/1.25 "Pretendard Variable",Pretendard,-apple-system,sans-serif;display:flex;flex-direction:column;gap:clamp(7px,1.6vmin,12px);overflow:hidden}.scene *{box-sizing:border-box}.title{font-weight:750;color:var(--accent)}.muted{color:var(--muted)}.mono{font-family:ui-monospace,monospace}.row{display:flex;align-items:center;justify-content:center;gap:clamp(5px,1.4vmin,12px);flex:1;min-height:0}.tile{border:1px solid var(--line);border-radius:8px;background:var(--bg);padding:clamp(6px,1.6vmin,12px);text-align:center;min-width:0}.on{border-color:var(--accent)!important;background:color-mix(in srgb,var(--accent) 12%,var(--surface))!important}.pulse{animation:pulse 1.6s infinite alternate}@keyframes pulse{to{border-color:var(--accent);transform:translateY(-3px)}}.transaction{border:2px dashed var(--accent);padding:8px;border-radius:8px;display:flex;align-items:center;justify-content:center;gap:8px}.transaction .tile{flex:1}.transaction span,.publish span{color:var(--accent)}.publish .tile{flex:1}
js
let phase=0;function tick(){['orderRow','outboxRow','commit','broker'].forEach((id,i)=>document.getElementById(id).classList.toggle('on',i<=(phase%4)));document.getElementById('outboxState').textContent=['Write order in transaction','Write outbox in same transaction','Commit both rows','Publisher delivers event'][phase%4];phase++}tick();setInterval(tick,820)

The outbox pattern commits business data and an event-to-publish row in the same database transaction. A separate publisher later sends the row to a broker, surviving a crash after commit.

The demo commits Order and Outbox together before publishing. Publishing may be retried, so consumers should handle duplicates.

When to use

Use it when a database write and message publish must not split into one-sided success.

Open as page ↗