Spring Batch Tasklet에서 예외 발생 시 Slave 커넥션 반환 실패 원인 분석

문제 요약

Spring Batch Tasklet 내부에서 슬레이브(readOnly) DataSource를 통해 조회를 수행 중 예외 발생 시, PlatformTransactionManager의 rollback 처리 후 커넥션이 반환되지 않는 문제가 발생하였습니다.

원인 분석

  • Tasklet 내부 로직이 try-catch만으로 예외를 흡수하고 throw를 하지 않음
  • TransactionTemplate rollback 발생 시 커넥션이 반환되지 않고 held 상태로 유지됨
  • Slave DataSource는 autoCommit=true라 해도 rollback 발생 시 Connection 종료가 보장되지 않음

개선 방안

  1. 조회 전용 커넥션 로직은 try-catch-finally 구조로 명시적으로 null 처리 or close
  2. 예외 발생 시 contribution.setExitStatus(ExitStatus.FAILED) 명시
  3. 중요: 커넥션 조회만 수행할 경우 트랜잭션 적용 대상인지 재검토

for (Map.Entry<String, DTO> entry : DTOs.entrySet()) {
    transactionTemplate.execute(status -> {
        try {
            ...
        } catch (Exception e) {
            log.error(...);
            status.setRollbackOnly(); // 💥 해당 항목만 롤백
        }
        return null;
    });
}
  

또는 명시적 반환 방식:


try {
    // 작업 수행
} catch (Exception e) {
    log.error("예외 발생", e);
    contribution.setExitStatus(ExitStatus.FAILED);

    // 💡 커넥션 명시적 반환 유도
    DataSourceUtils.releaseConnection(connection, dataSource);
    return RepeatStatus.FINISHED;
}
  

관련 글

답글 남기기

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