아웃박스 패턴은 업무 데이터와 발행 예정 이벤트를 같은 DB 트랜잭션에 저장합니다. 별도 발행자가 아웃박스 행을 읽어 브로커로 보내므로 DB 저장 직후 프로세스가 죽어도 이벤트를 잃지 않습니다.
데모에서는 주문과 아웃박스가 함께 커밋되고 그 뒤 이벤트가 발행됩니다. 발행자는 같은 이벤트를 다시 보낼 수 있으므로 소비자 중복 처리를 준비해야 합니다.
언제 쓰나
DB 저장과 메시지 발행 중 하나만 성공하는 상태를 피해야 할 때 사용합니다.
DB 변경과 발행할 이벤트를 같은 트랜잭션에 기록합니다.
<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>.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}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)아웃박스 패턴은 업무 데이터와 발행 예정 이벤트를 같은 DB 트랜잭션에 저장합니다. 별도 발행자가 아웃박스 행을 읽어 브로커로 보내므로 DB 저장 직후 프로세스가 죽어도 이벤트를 잃지 않습니다.
데모에서는 주문과 아웃박스가 함께 커밋되고 그 뒤 이벤트가 발행됩니다. 발행자는 같은 이벤트를 다시 보낼 수 있으므로 소비자 중복 처리를 준비해야 합니다.
DB 저장과 메시지 발행 중 하나만 성공하는 상태를 피해야 할 때 사용합니다.