Spring Batch에서 slave DB 커넥션 반환 문제와 MyBatis + Hikari 트랜잭션 실전 가이드

🔹 문제 인식

  • Spring Batch에서 slave DB에서 SELECT 쿼리 수행 후, masterINSERT 작업을 하는 구조에서,
    slave 커넥션이 반환되지 않아 커넥션 풀 고갈 발생 가능
  • 특히, MyBatis + Spring 트랜잭션 환경에서는 커넥션 반환 타이밍이 복잡하게 엮임
  • HikariCP의 auto-commit=true 설정에도 불구하고, 커넥션이 즉시 반환되지 않음

🔹 핵심 원인

  • auto-commit=true는 JDBC 레벨의 기본 동작일 뿐
  • MyBatis는 내부적으로 트랜잭션처럼 동작하며, SqlSessionTemplate이 커넥션을 유지
  • Spring 트랜잭션이 시작되면 setAutoCommit(false)가 적용되어 반환 시점이 명시적 트랜잭션 종료 시점으로 지연됨

🔹 해결 방법

✅ 1. TransactionTemplate으로 slave 트랜잭션 분리

List<Data> list = slaveTxSupport.read(() -> slaveMapper.selectByCondition(paramA, paramB));
  • readOnly=true 설정으로 성능 최적화
  • 쿼리 실행 후 트랜잭션 자동 종료 → 커넥션 즉시 반환

✅ 2. chunk 방식에서 ListItemReader에 적용 가능

@Bean
@StepScope
public ListItemReader<Entity> reader() {
return new ListItemReader<>(
slaveTxSupport.read(() -> mapper.selectList(param))
);
}
  • chunk 트랜잭션 시작 전에 slave 쿼리 처리 → 안전하게 분리됨

✅ 3. 커넥션 반환 여부 확인

  • HikariPoolMXBean을 통해 JConsole이나 VisualVM으로 확인 가능
  • 또는 datasource-proxy를 사용해 커넥션 획득/반환 로그 확인 가능
  • leak-detection-threshold 설정 시 누수 경고도 감지 가능

🔹 MyBatis Interceptor에서 커넥션 직접 반환은?

  • Spring 환경에서는 비권장
  • Spring의 TransactionSynchronizationManager와 충돌할 수 있음
  • 커넥션은 트랜잭션 종료 후 Spring이 관리하는 흐름에 맡기는 것이 가장 안전함

✅ 결론

  • slave DB 조회는 TransactionTemplate으로 read-only 트랜잭션을 분리하자
  • master 쓰기는 Step 트랜잭션에 맡기고, 구조는 명확하게 분리
  • Hikari 커넥션 풀 모니터링도 설정해서 커넥션 누수 감지를 강화하자

관련 글

답글 남기기

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