중복 게시 0을 노리는 outbox 패턴
외부 API 성공과 DB 기록 사이의 빈칸 때문에 생기는 중복 게시를 outbox 상태머신과 reconcile로 줄이는 실전 구조를 정리했어요.
중복 게시 0을 노리는 outbox 패턴
API 호출은 성공했는데 DB 기록 전에 프로세스가 죽으면, 중복 게시 0은 생각보다 어렵습니다. 직접 만들어보니 문제는 같은 row를 두 번 잡는 쪽보다, 외부 성공과 내부 기록 사이에 생기는 빈칸을 어떻게 다루느냐에 더 가깝더라고요. 라이프케어로그처럼 혼자 운영하는 파이프라인일수록 이 틈을 먼저 막아두는 편이 안전해요.
왜 UNIQUE만으로는 부족할까
테스트해 보면 published 한 줄만 믿는 구조는 금방 흔들려요. 2026-07-23에 정리한 outbox 상태머신도 이 구간을 기준으로 잡았고, 핵심은 claimed → sending → published 3단계와 retryable_failed, permanent_failed, reconcile_required 3개 실패 상태를 분리하는 거예요. 특히 sending에서 lease가 만료되면 자동 재전송하지 않고 reconcile_required로 격리해요. 외부에 이미 올라갔는지 모르는 상태에서 다시 보내면 그때 중복이 생기기 때문이에요.
실전에서는 lease와 재시도를 같이 봐야 해요
적용해 봤더니 claim만 안전해도 끝나지 않았어요. blog 워커는 10분 lease로 건을 선점하고, 15분 주기로 초안을 넘겨요. 반대로 reconcile 잡은 10분마다 만료된 sending을 모아 사람 확인 대상으로 올려요. 여기에 최대 5회 재시도, 60분 cap backoff, 0~30초 jitter를 두면 5xx나 일시 장애에도 덜 흔들려요.
제가 남긴 운영 포인트
직접 돌려 보니 블로그 채널의 published 의미도 분리해야 했어요. 이 파이프라인에서 published는 웹 라이브가 아니라 publish:false 초안을 넘겼다는 뜻이고, 실제 배포는 별도 게이트가 맡아요. 이 경계를 나눠야 git 푸시와 게시 확인이 섞이지 않아요. 라이프케어로그처럼 작은 도구를 여러 개 운영하면, outbox는 화려한 패턴보다 사고 범위를 줄이는 장치에 더 가까워요. 먼저 상태를 쪼개고, 모르면 재전송하지 않는 쪽으로 시작해 보세요.
관련 글
댓글
아직 댓글이 없어요. 첫 댓글을 남겨주세요.