Zettelkasten

Transactional Outbox 생성 후 즉시 발송하는 로직은 Polling을 최적화한 방법이다.

·수정 2026.04.23·수정 1

요약

  • 즉시 전송(Immediate dispatch)은 독립적인 방식이 아니라 Polling의 최적화 레이어다
  • 즉시 전송을 사용하더라도 실패 fallback을 위해 Polling 워커는 필수

본문

두 가지 처리 방식

방식 설명
즉시 전송 Outbox에 추가 후 바로 외부 시스템 호출
Polling 워커가 일정 주기로 Outbox를 확인해 처리

선택 기준

기준 즉시 전송 Polling
지연 허용 ❌ 즉시 필요 ✅ 수 초~분 OK
처리량 낮음 (수십 TPS) 높음 (수백+ TPS)
API 응답 속도 느려도 됨 빨라야 함
외부 시스템 안정성 안정적 불안정/Rate limit

왜 즉시 전송에도 Polling이 필요한가?

Outbox 저장과 외부 시스템 호출은 트랜잭션으로 묶이지 않는다:

BEGIN → Outbox INSERT → COMMIT (성공) → 외부 API 호출 (실패 가능)

실패 시나리오:

  1. Outbox 저장 성공 (DB 트랜잭션 커밋)
  2. 외부 시스템 호출 실패 (네트워크 오류, 타임아웃, Rate limit 등)
  3. → Outbox에 미처리 레코드로 남음
  4. → Polling 워커가 이를 재처리

하이브리드 패턴 (권장)

def process(event):
    with transaction():
        save(event)
        outbox.insert(event, status='PENDING')

    # 즉시 시도 (best-effort)
    try:
        send_to_external(event)
        outbox.delete(event)
    except:
        pass  # 실패해도 OK → Polling이 처리

# Polling 워커는 항상 돌면서 미처리 건 수습

실무 적용

  • 처리량 높을 예정: 처음부터 Polling 전용으로 설계
  • 즉시 전송 추가: 성능 최적화 단계에서 고려
  • 핵심: 즉시 전송은 "있으면 좋은 것", Polling은 "필수"

참고