주문을 저장한 뒤 메시지 브로커에 '주문 생성' 이벤트를 보내는 서비스가 있습니다. DB 저장은 성공하고 메시지 전송만 실패하면 다른 시스템은 주문을 모릅니다. 두 저장소를 한 번에 완벽히 쓰기 어렵다면 이벤트를 DB 트랜잭션 안에 함께 남기는 아웃박스 패턴을 검토할 수 있습니다.
두 번 쓰기의 실패 지점을 찾는다
DB에 먼저 저장하고 나중에 메시지를 보내면 그 사이에 프로세스가 멈출 수 있습니다. 메시지를 먼저 보내면 DB 저장이 실패했는데 다른 서비스가 일을 시작할 수 있습니다. 순서만 바꿔 해결할 수 있는 문제가 아닙니다.
업무 행과 발행할 이벤트 행을 같은 DB 트랜잭션에 넣으면 둘이 함께 확정되거나 함께 취소됩니다. 이벤트 전송은 이후 별도 작업자가 맡습니다.
아웃박스 행의 내용을 정한다
이벤트 ID, 유형, 대상 ID, 업무 버전, 생성 시각과 필요한 페이로드를 저장합니다. 개인정보 전체를 복제하지 않도록 목적에 필요한 필드만 담습니다.
발행 작업자는 미전송 행을 읽고 브로커에 보낸 뒤 상태를 갱신합니다. 이 과정에서도 전송은 성공했지만 상태 갱신이 실패할 수 있으므로 중복 전송을 전제로 설계합니다.
구독자도 중복에 대비한다
같은 이벤트 ID를 두 번 받아도 결과가 한 번 처리된 것과 같아야 합니다. 처리한 이벤트 ID를 기록하거나 업무 상태 전환을 멱등하게 설계합니다.
이벤트 순서도 중요할 수 있습니다. 동일 주문의 생성과 취소가 뒤바뀌면 잘못된 상태가 됩니다. 주문별 버전이나 순서 키를 활용해 오래된 이벤트를 처리하지 않도록 합니다.
가상 사례: 주문 확정 뒤 메시지 서버 장애
주문은 확정됐지만 메시지 서버가 잠시 응답하지 않는다고 가정해 봅시다. 아웃박스 기록은 DB에 남고 발행 작업자가 나중에 전송을 재시도할 수 있습니다.
사용자 화면에는 주문 확정과 후속 알림 대기를 다른 상태로 보여 줄 수 있습니다. 후속 업무가 반드시 끝난 것처럼 표시하면 안 됩니다. 사례는 가상의 설명입니다.
지연과 실패를 운영한다
아웃박스의 미발행 건수, 가장 오래된 건의 대기 시간, 반복 실패 이유를 모니터링합니다. 재시도만 무한히 하면 잘못된 데이터가 계속 큐를 막을 수 있습니다.
정해진 횟수 뒤 별도 검토로 보내고 수정 후 다시 발행할 수 있게 합니다. 완료된 행의 보관 기간과 감사 요구도 결정합니다.
현장에 적용할 때의 순서
- 업무 기록과 이벤트를 함께 커밋한다
- 발행 작업자의 재시도 상태를 둔다
- 구독자의 중복 처리를 검증한다
주의할 실패: 브로커 전송 뒤 상태 기록이 실패하면 같은 이벤트가 다시 전달될 수 있다.
관찰할 지표: 가장 오래된 미발행 건과 중복 수신률을 관찰한다.
적용 전 체크리스트
- 업무 데이터와 이벤트가 같은 트랜잭션에 저장되는가
- 구독자가 중복·역순 이벤트를 처리하는가
- 아웃박스 적체와 실패 건을 관찰하는가
참고 자료
AWS Transactional Outbox Pattern. AWS 공식 패턴 설명의 이중 쓰기와 중복 전송 고려 사항을 참고했습니다. 구체적인 상태·보관 정책은 서비스별로 정해야 합니다.
이미지와 도식은 이해를 돕기 위한 개념 시각화입니다. 특정 고객의 실제 설비·데이터·화면을 재현한 것이 아닙니다.
#트랜잭셔널아웃박스 #이벤트발행 #분산시스템 #DB정합성 #메시지큐 #멱등성 #이벤트아키텍처 #마이크로서비스 #재시도 #백엔드