ADR-002: Outbox 패턴 도입 검토

ADR-002: Outbox 패턴 도입 검토

  • 상태: 보류 (Deferred)
  • 날짜: 2026-03-08
  • 의사결정자: Oracle (심판관)

컨텍스트

Submission 서비스는 제출 처리 시 DB 저장과 RabbitMQ 메시지 발행을 순차적으로 수행한다. 이 두 작업은 원자적이지 않아, DB 커밋 후 MQ 발행 실패 시 데이터 불일치가 발생할 수 있다.

현재 흐름:

  1. DB에 Submission 저장 (커밋)
  2. RabbitMQ에 분석 요청 메시지 발행
  3. 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 (현행 유지 + 보완) 채택.

근거:

  1. OCI ARM 단일 인스턴스(4 OCPU / 24GB)에서 Outbox Polling이나 CDC 인프라를 추가 운영하기에는 리소스가 부족하다.
  2. 현재 트래픽 수준(스터디 그룹 단위, 동시 사용자 수십 명)에서는 DB-MQ 비원자성으로 인한 실제 장애 발생 확률이 극히 낮다.
  3. Timeout 재개 메커니즘이 유실된 메시지를 자동 복구하므로, 최종적 일관성은 보장된다.

재검토 트리거

다음 조건 충족 시 옵션 A(Outbox 패턴) 도입을 재검토한다:

  • 동시 사용자 500명 이상 또는 일일 제출 1,000건 이상
  • Timeout 재개로 인한 중복 처리가 월 10건 이상 발생
  • 인프라 스케일업 (멀티 노드 전환 등)으로 리소스 여유 확보