transactional-outbox-pattern.spec

문제정의

WHY:

현재 시스템은 애그리거트의 상태 변경과 이벤트 저장을 단일 트랜잭션으로 묶는 'Event Store' 방식을 훌륭하게 구현하여 데이터의 원천(Source of Truth)을 확보했습니다. 하지만 이벤트를 EventEmitter2로 발행하는 과정이 동일 트랜잭션 혹은 직후의 메모리 상에서 이루어지고 있어, 애플리케이션 크래시나 리스너 장애 발생 시 **이벤트 발행의 유실(At-Least-Once delivery 실패)**이 발생할 위험이 존재합니다. 이를 해결하고 궁극적으로 Kafka 도입을 위한 안전한 교두보를 마련하기 위해 완벽한 Transactional Outbox Pattern의 완성이 필요합니다.

WHERE:

WHAT:

기존 event_store에 이벤트 발행 여부를 추적할 수 있는 상태 필드를 추가하고, 발행되지 않은 이벤트를 폴링(Polling)하여 EventEmitter2(향후 Kafka)로 전달한 뒤 상태를 업데이트하는 Event Relay Worker를 구현합니다.

예상 개발기간, 소요시간

IN-SCOPE

OUT-SCOPE

DEPENDENCY

RISK

TIME-ESTIMATED

16hr (스키마 변경, Worker 구현, 컨슈머 멱등성 점검 및 테스트 포함)

마스터리스트 (평가지표 체크리스트)

이 태스크가 완료 상태로 바뀌기 위해 통과하여야 하는 조건들을 나열하는 마스터테이블입니다.

항목명 설명 검증 방법 ⌛️🏃✅❌
스키마 마이그레이션 event_store에 발행 상태 추적 필드 추가 및 인덱스 생성 DB 스키마 확인 및 인덱스 적용 여부 확인 ⌛️
Relay Worker 동작 스케줄러가 미발행 이벤트를 정상적으로 가져오는지 확인 로그 및 디버깅을 통한 쿼리 실행 확인 ⌛️
이벤트 발행 및 상태 갱신 이벤트를 Dispatcher에 태운 후 DB 상태가 published로 변경되는지 확인 테스트 코드 (Worker 실행 후 DB 상태 Assert) ⌛️
장애 복구 (Retry) Dispatch 실패 시 이벤트를 유실하지 않고 다음 주기에 재시도하는지 확인 Dispatcher에 의도적 예외 주입 후 재시도 여부 확인 ⌛️
컨슈머 멱등성 보장 동일한 이벤트가 2번 이상 인입되었을 때 시스템 상태가 1번 처리된 것과 동일한지 확인 동일 이벤트 Payload를 연속 2회 발행하여 결과 상태 Assert ⌛️

Usecase Scenarios

UC00: 미발행 이벤트의 릴레이(Relay) 및 상태 업데이트

[액터]

Event Relay Worker (NestJS Background Task)

[전제조건]

[시나리오]

  1. Event Relay Worker가 설정된 주기(예: 2초)마다 실행된다.

  2. event_store에서 publishedAt: null 인 이벤트를 설정된 Batch Size(예: 100건)만큼 시간순으로 조회한다.

  3. 조회된 이벤트를 순회하며 Event Bus(EventEmitter2)로 이벤트를 발행(Dispatch)한다.

  4. 이벤트 발행이 성공하면, 해당 이벤트의 ID를 모아 event_storepublishedAt: new Date()로 업데이트한다.

[사후조건]

[예외흐름]

참고자료

관련 회의록 링크