#Backend

“장보기 지원금이 곧 소멸돼요” 알림 뒤에서 일어난 일

“장보기 지원금이 곧 소멸돼요” 알림 뒤에서 일어난 일
01

Summary

배치가 DB 커넥션을 붙잡고 있다면? SSG.COM의 배치 트랜잭션 다이어트 전략

API 응답을 기다리는 동안 소중한 DB 자원을 놀리지 않고 효율적으로 해제하는 최적화 노하우

SSG.COM 테크 블로그에서 대규모 알림 시스템의 안정성을 확보하기 위해 진행한 DB 리소스 최적화 사례를 다룹니다. 단순히 배치 속도를 높이는 것보다, 외부 API 호출 시 발생하는 리소스 점유 병목을 어떻게 해결했는지가 핵심입니다. Spring Batch의 트랜잭션 관리 전략을 수정하여 인프라 효율성을 극대화한 실무적인 접근 방식을 보여줍니다.

  • 01수십만 건의 알림 대상자를 처리하는 배치의 병렬 구조 최적화 과정 공유
  • 02Spring Batch Chunk 프로세스 내 API 호출이 DB 커넥션 타임아웃에 미치는 영향 분석
  • 03ResourcelessTransactionManager를 활용한 트랜잭션 책임 범위 조정 및 리소스 분리
  • 04커넥션 풀(Connection Pool)의 고갈 문제를 해결하여 시스템 전체의 안정성 제고
  • 05배치 작업 시 '무엇을 붙잡고 기다리는지'에 대한 엔지니어링 관점의 인사이트 제공

RECOMMENDATION

외부 API 호출이 포함된 Spring Batch를 운영 중인 백엔드 개발자라면, 트랜잭션 내부에서 불필요하게 DB 커넥션을 점유하고 있지는 않은지 이 아티클을 통해 점검해보시길 권장합니다.

The Problem

대량의 고객에게 소멸 예정 알림을 발송하는 배치 작업 중, 외부 API 호출 시 응답을 대기하는 동안 DB 커넥션을 계속 점유하여 커넥션 타임아웃과 배치 실패가 발생하는 문제가 있었습니다. 병렬 처리 도입 이후 처리 속도는 빨라졌으나, 여러 스레드가 동시에 커넥션을 점유하면서 Connection Pool에 가해지는 부담이 더욱 커졌습니다.

The Solution

Spring Batch의 Chunk 트랜잭션 범위를 조정하고 ResourcelessTransactionManager를 도입하여 DB 리소스를 사용하는 구간과 외부 API 응답을 대기하는 구간을 명확히 분리했습니다. 이를 통해 메시지 발송 API 호출로 인한 대기 시간이 DB 커넥션 점유로 이어지지 않도록 구조를 개선했습니다.

The Result

메시지 발송 대기 시 불필요한 DB 커넥션 점유를 차단함으로써 Connection Pool의 부담을 완화하고, 간헐적으로 발생하던 배치 실패 문제를 해결하여 대량 발송 시의 시스템 안정성을 확보했습니다.

Trade-off

해당 방식은 트랜잭션 정합성보다 리소스 효율성이 중요한 배치에 적합하며, 데이터 읽기 방식이나 처리 흐름에 따라 DB 커넥션 반환 시점이 달라질 수 있으므로 각 배치 특성에 맞는 정밀한 검증이 필요합니다.

03

Key Concepts

Concept · 01

Spring Batch Chunk Model

대용량 데이터를 일정한 단위(Chunk)로 나누어 Reader, Processor, Writer 과정을 거쳐 처리하는 Spring Batch의 핵심 메커니즘입니다.

  • 기존 구조에서는 Chunk 단위의 트랜잭션이 DB 커넥션과 API 호출을 하나로 묶어 관리하고 있었습니다.
Concept · 02

ResourcelessTransactionManager

실제 리소스에 대한 트랜잭션을 관리하지 않는 가상의 TransactionManager로, DB 연결 없이 실행되는 스텝에서 유용합니다.

  • 메시지 발송 API 호출 시 DB 커넥션을 불필요하게 유지하지 않도록 트랜잭션의 성격을 변경하는 데 사용되었습니다.
Concept · 03

Connection Pool Management

한정된 데이터베이스 연결 자원을 효율적으로 관리하기 위해 커넥션을 미리 생성해 두고 재사용하는 기법입니다.

  • API 응답 대기 시간만큼 커넥션이 풀로 반환되지 못해 발생하는 병목 현상을 해결하는 것이 이번 개선의 핵심 목표였습니다.