DataSource 커넥션 반환 누락 또는 수동 반환 필요

🧩 문제 현상

  • Tasklet 내부 반복 로직 중 일부 예외 발생 시 커넥션 반환이 이루어지지 않아 HikariCP 커넥션 풀 고갈 발생
  • 이로 인해 다음 반복 구간부터 커넥션 할당 실패, Job 전체 장애 또는 재시작 필요

🔍 원인 분석

  • 예외 발생 시 catch 블록에서 contribution.setExitStatus(ExitStatus.FAILED) 로만 처리하고, throw 하지 않으면 rollback은 수행되지만 커넥션이 반환되지 않을 수 있음
  • 특히 직접 JDBC 커넥션을 받아 사용하는 경우 수동 반환 필수

🛠 해결 방법

  1. 개별 항목마다 트랜잭션 분리 (TransactionTemplate 활용)
    for (Map.Entry<String, DataFeedDTO> entry : dataFeedDTOs.entrySet()) {
    transactionTemplate.execute(status -> {
    try {
    // 처리 로직
    } catch (Exception e) {
    log.error("처리 중 오류 발생: {}", entry.getKey());
    status.setRollbackOnly(); // 해당 항목만 롤백
    } return null; });
    }
  2. catch 블록에서 명시적 커넥션 반환
    try {
    // 커넥션 사용하는 로직
    } catch (Exception e) {
    contribution.setExitStatus(ExitStatus.FAILED);
    DataSourceUtils.releaseConnection(connection, dataSource); // 💡 수동 반환 return
    RepeatStatus.FINISHED;
    }
  3. TransactionTemplate 선언 방식
    @Autowired @Qualifier("yourTransactionManager")
    private PlatformTransactionManager transactionManager;
    private final TransactionTemplate transactionTemplate;
    @PostConstruct public void init() {
    this.transactionTemplate = new TransactionTemplate(transactionManager);
    }

✅ 적용 후 기대 효과

  • 개별 항목 단위 롤백이 가능해져서 전체 작업 중단 없이 실패 항목만 건너뜀
  • 수동 커넥션 반환을 통해 HikariCP 커넥션 누수 방지
  • 안정적인 트랜잭션 관리 및 자원 회수 보장

관련 글

답글 남기기

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