본문 바로가기
나의 개발/로직 설계

NestJS + TypeORM에서 대댓글 & 푸시 알림 트랜잭션 설계 정리

by Parkej 2025. 12. 31.

 

댓글에 대댓글이 달릴 때 원댓글 작성자에게 푸시 알림을 보내는 기능은 많은 서비스에서 자연스럽게 등장한다.

문득 이런 생각이 들었다.

“대댓글 생성과 푸시 알림을 어디까지 보장해야 할까?”

 

이 글에서는 나의 고민점들과 해법을 통한 비즈니스 중요도에 따른 2단계 설계 방식을 정리한다.

또한 외부 API를 연동할 때 꼭 이런 고민을 고려해봐야 할 것 같다.


내 고민

외부 API를 연동하면서 로직을 고려할 때 봐야할 것은 대댓글푸시 알림이다. 

 

IF

  • 이 두개를 다 가져가려면? 
  • DB 저장에 성공했는데 푸시알림이 전송안되면
    • 외부 API 오류
    • 비동기 처리 즉, Bull queue라면 redis 오류나 Bull queue 자체의 오류
    • 등등
  • DB 저장에 실패했는데 푸시알림이 전송되면?
    • DB 장애
    • 로직적 오류
    • 등등
  • 푸시 알림이 실패되고 그냥 놔둘건지 아니면 재전송을 할건지 만약 재전송을 한다면 어떻게 할거고 어떤식으로 기록을 남길것인지 (로그, 추적, 재발송, 복구 등)

문제 상황

  • 대댓글 생성: 핵심 비즈니스 기능 (반드시 보장)
  • 푸시 알림:
    • UX 개선을 위한 부가 기능일 수도 있고
    • 하나의 완료 조건일 수도 있다

이 판단에 따라 트랜잭션 경계와 비동기 처리 방식이 완전히 달라진다.


1단계: 푸시 알림을 “부가 기능”으로 보는 경우

핵심 목표

대댓글이 DB에 없는데 알림만 전송되는 상황을 방지


설계 방식

  • 대댓글 저장을 DB 트랜잭션으로 보장
  • 트랜잭션 커밋 이후 푸시 알림 job을 비동기로 생성
await queryRunner.startTransaction();
await queryRunner.manager.save(reply);
await queryRunner.commitTransaction();

// commit 이후
queue.add('send-push', payload).catch(console.error);

보장되는 것

  • 대댓글 저장은 트랜잭션으로 보장됨
  • 대댓글이 커밋되지 않았는데
    푸시 job이 큐에 들어가는 상황은 발생하지 않음
  • 이른바 “유령 알림” 방지

허용하는 것

  • 알림 누락 가능
    • Redis 장애
    • queue.add 실패
    • commit 직후 서버 다운
  • 알림 재시도/추적 어려움

장점

  • 구현 단순
  • 개발 속도 빠름
  • 운영/관리 포인트 적음
  • 인프라 비용 낮음

단점

  • 알림 신뢰성 낮음
  • 알림 누락에 대한 보완 수단 없음
  • 알림이 중요해지면 구조 변경 필요

적합한 비즈니스 상황

  • 알림은 UX 보조 요소
  • 알림 누락이 서비스 품질에 큰 영향을 주지 않음
  • 초기 서비스 / MVP / 소규모 트래픽

2단계: 푸시 알림을 “기능의 일부”로 보는 경우

핵심 목표

“대댓글 생성 완료” = “알림 요청이 반드시 생성됨”


설계 방식 (Transactional Outbox 패턴)

  • 대댓글 저장
  • 알림 작업(outbox) 생성
  • 같은 DB 트랜잭션 안에서 커밋
await queryRunner.startTransaction();

await queryRunner.manager.save(reply);
await queryRunner.manager.save(NotificationOutbox, {
  type: 'REPLY_CREATED',
  payload,
  status: 'PENDING',
});

await queryRunner.commitTransaction();
  • 별도의 워커가 outbox를 읽어 푸시 전송

보장되는 것

  • 대댓글이 없는데 알림 요청이 생기는 상황 ❌
  • 대댓글이 생성됐는데 알림 요청 자체가 사라지는 상황 ❌
  • 알림 실패 시 재시도 가능
  • 알림 성공/실패 상태 추적 가능

허용하는 것

  • 실시간성 일부 희생 (eventual consistency)
  • 시스템 복잡도 증가

장점

  • 알림 신뢰성 매우 높음
  • 장애 상황에서도 데이터 정합성 유지
  • 재처리/모니터링 가능
  • SLA 정의 가능

단점

  • 구현 난이도 상승
  • 관리 포인트 증가 (테이블, 워커, 모니터링)
  • 운영 비용 상승

적합한 비즈니스 상황

  • 알림이 서비스 핵심 가치
  • 알림 누락이 CS/이탈로 직결
  • 사용자 규모가 큰 서비스
  • 운영/모니터링 체계가 존재

두 방식 비교 요약

구분 1단계 (부가 기능) 2단계 (핵심 기능)
대댓글 보장
유령 알림 방지
알림 누락 허용 허용 안 함
재시도/추적
구현 난이도 낮음 높음
운영 복잡도 낮음 높음
비용 낮음 높음
적합 시기 초기/MVP 성장/핵심 서비스

결론

푸시 알림을 어디까지 보장할지는 기술 문제가 아니라 비즈니스 판단이다.

  • 알림이 부가 기능이라면 커밋 이후 비동기 처리
  • 알림도 완료 조건이라면 Transactional Outbox

처음부터 완벽한 구조를 만들 필요는 없다.
서비스 성장 단계에 맞는 선택이 가장 중요하다.

 

반응형

댓글