ADR-002: Outbox 패턴 도입 검토
ADR-002: Outbox 패턴 도입 검토
- 상태: 보류 (Deferred)
- 날짜: 2026-03-08
- 의사결정자: Oracle (심판관)
컨텍스트
Submission 서비스는 제출 처리 시 DB 저장과 RabbitMQ 메시지 발행을 순차적으로 수행한다. 이 두 작업은 원자적이지 않아, DB 커밋 후 MQ 발행 실패 시 데이터 불일치가 발생할 수 있다.
현재 흐름:
- DB에 Submission 저장 (커밋)
- RabbitMQ에 분석 요청 메시지 발행
- GitHub Worker에 푸시 요청 메시지 발행
위험 시나리오:
- 1 성공 + 2 실패: 제출은 저장되었으나 AI 분석이 시작되지 않음
- 1 성공 + 3 실패: 제출은 저장되었으나 GitHub 푸시가 실행되지 않음
현재 보완책 (Sprint 43 W2 적용)
- 낙관적 락: Saga 상태 변경 시 version 컬럼으로 Lost Update 방지
- Timeout 재개: 일정 시간 내 완료되지 않은 Saga를 cron으로 감지하여 재시작
- 멱등성 체크: 각 워커가 중복 메시지를 감지하여 재처리 방지 (idempotency key)
이 보완책들로 인해 메시지 유실 시에도 timeout 재개를 통해 최종적 일관성(eventual consistency)이 보장된다.
검토 옵션
옵션 A: Outbox 테이블 + Polling Publisher
DB 트랜잭션 내에서 Outbox 테이블에 메시지를 함께 저장하고, 별도 Polling Publisher가 주기적으로 Outbox를 조회하여 MQ에 발행한다.
장점:
- DB 저장과 메시지 발행의 원자성 보장
- 메시지 유실 가능성 제거
단점:
- Outbox 테이블 + Polling 서비스 추가 운영 부담
- Polling 지연으로 인한 처리 latency 증가
- OCI ARM 단일 인스턴스에서 추가 리소스 소모
옵션 B: CDC (Change Data Capture, Debezium 등)
PostgreSQL WAL을 캡처하여 변경 이벤트를 MQ로 자동 발행한다.
장점:
- 애플리케이션 코드 변경 최소화
- 실시간에 가까운 이벤트 전파
단점:
- Debezium + Kafka Connect 인프라 필요 (리소스 과다)
- OCI ARM 4 OCPU / 24GB 환경에서 운영 비현실적
- 운영 복잡도 대폭 증가
옵션 C: 현행 유지 + 보완 (현재 채택)
Sprint 43 W2에서 적용한 낙관적 락 + timeout 재개 + 멱등성 체크를 유지한다.
장점:
- 추가 인프라 불필요
- 현재 트래픽 수준에서 충분한 안정성
- 운영 복잡도 최소
단점:
- 이론적 메시지 유실 가능성 존재 (timeout 재개로 복구)
- 트래픽 급증 시 timeout 재개 부하 증가 가능
결정
옵션 C (현행 유지 + 보완) 채택.
근거:
- OCI ARM 단일 인스턴스(4 OCPU / 24GB)에서 Outbox Polling이나 CDC 인프라를 추가 운영하기에는 리소스가 부족하다.
- 현재 트래픽 수준(스터디 그룹 단위, 동시 사용자 수십 명)에서는 DB-MQ 비원자성으로 인한 실제 장애 발생 확률이 극히 낮다.
- Timeout 재개 메커니즘이 유실된 메시지를 자동 복구하므로, 최종적 일관성은 보장된다.
재검토 트리거
다음 조건 충족 시 옵션 A(Outbox 패턴) 도입을 재검토한다:
- 동시 사용자 500명 이상 또는 일일 제출 1,000건 이상
- Timeout 재개로 인한 중복 처리가 월 10건 이상 발생
- 인프라 스케일업 (멀티 노드 전환 등)으로 리소스 여유 확보