Spring Batch Tasklet 트랜잭션 내 개별 항목 실패 시 커넥션 누수 방지 방법

문제 요약

Tasklet 내부에서 루프를 돌며 개별 항목을 처리할 때, 예외가 발생해도 catch 블럭 내에서 로그만 찍고 다음 항목으로 진행하는 방식은 커넥션 반환이 제대로 되지 않아 HikariCP 커넥션 풀에서 누수가 발생할 수 있음.

개선 방안

  • 루프 내에서 각 항목을 처리할 때 TransactionTemplate을 이용하여 부분 롤백 처리
  • catch 블럭에서는 status.setRollbackOnly()로 트랜잭션만 롤백
  • 예외 발생 후 contribution.setExitStatus(ExitStatus.FAILED)DataSourceUtils.releaseConnection()를 통해 수동 커넥션 반환

예제 코드


for (Map.Entry<String, TO> entry : TOs.entrySet()) {
    transactionTemplate.execute(status -&gt; {
        try {
            // 항목별 처리 로직
        } catch (Exception e) {
            log.error("처리 중 오류 발생", e);
            status.setRollbackOnly(); // 💥 해당 항목만 롤백
        }
        return null;
    });
}
  

예외 발생 시 명시적 커넥션 반환


try {
    // 실패해도 다음 항목 계속 처리
} catch (Exception e) {
    log.error("오류 발생", e);
    contribution.setExitStatus(ExitStatus.FAILED);

    // 커넥션 명시적으로 반납
    DataSourceUtils.releaseConnection(connection, dataSource); 
    return RepeatStatus.FINISHED;
}
  

효과

  • 불필요한 커넥션 점유 해소
  • OOM 또는 커넥션 부족으로 인한 배치 실패 예방
  • 로컬 혹은 클러스터 환경에서 안정적인 병렬 처리 가능

관련 글

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다