피드로 돌아가기
SQS 기반 알림톡 처리에서 발생한 DB 커넥션 데드락 분석기
올리브영 테크블로그올리브영 테크블로그
Backend

SQS 기반 알림톡 처리에서 발생한 DB 커넥션 데드락 분석기

올리브영이 SQS 기반 이벤트 구조로 알림톡 시스템을 전환했으나 30초 DB 커넥션 데드락 발생 → REQUIRES_NEW 제거 및 폴링 메시지 한도 조정으로 타임아웃 0건 달성

2025년 12월 30일12intermediate

Context

기존 알림톡 발송 로직이 각 비즈니스 로직에 산재되어 있었으며, 외부 API 호출이 비즈니스 트랜잭션 내부에서 강하게 결합되어 있었다. 외부 API 지연이나 네트워크 이슈 발생 시 전체 트랜잭션이 대기 상태에 빠져 시스템 처리량이 저하되는 구조였다.

Technical Solution

  • Amazon SQS 기반 이벤트 구조 도입: 비즈니스 로직에서 최소 데이터만 담아 SQS 메시지로 발행하고, Consumer 서버에서 비동기로 처리하도록 분리
  • NoticeSender 공통 인터페이스 구현: 알림 발송 흐름(검증 → 템플릿 생성 → 메시지 생성 → 발송 → 저장)을 하나의 파이프라인으로 일원화하여 알림 유형별 독립 확장 가능하게 변경
  • 트랜잭션 결합 해소: 비즈니스 로직의 트랜잭션을 SQS 발행 시점까지로 제한하여 알림 발송 성공 여부와 무관하게 빠르게 종료
  • Amazon EventBridge를 통한 재시도 구조 도입: DB 기반 실패 이력 관리 + 주기적 재시도 API 호출로 실패 건 추적 및 개별 재처리 가능하게 구현
  • DB 커넥션 풀 설정 최적화: REQUIRES_NEW 트랜잭션 전파 옵션 제거로 스레드당 필요 커넥션 수를 2개에서 1개로 감소, SQS maxNumberOfMessages를 커넥션 풀 크기 이하로 조정

Impact

Java HikariPool 타임아웃 오류(java.sql.SQLTransientConnectionException: Connection is not available, request timed out after 30008ms)가 0건으로 감소.

Key Takeaway

SQS 폴링 병렬 처리와 트랜잭션 전파 옵션이 DB 커넥션 풀 크기와 결합될 때 발생하는 데드락 임계점을 이해해야 한다. 최소 필요 커넥션 수 = Tn × (Cm - 1) + 1 공식(Tn: 동시 처리 스레드 수, Cm: 스레드당 최대 커넥션 수)을 기준으로 커넥션 풀과 폴링 메시지 개수를 함께 튜닝하는 것이 필수적이다.


SQS, Kafka 등 폴링 기반 메시지 큐를 사용하는 비동기 처리 시스템에서는 @Transactional(propagation = Propagation.REQUIRES_NEW) 옵션 사용을 최소화하고, maxNumberOfMessages 또는 동등 설정값이 DB 커넥션 풀 크기(HikariCP maximumPoolSize)를 초과하지 않도록 설정해야 대규모 병렬 처리 환경에서 데드락을 피할 수 있다.

원문 읽기