질문 시나리오
Spring Batch Tasklet 안에서 slaveMapper
를 사용하는 다음 코드처럼:
slaveTxSupport.read(() -> slaveMapper.selectSomething());
slaveTxSupport.read(() -> slaveMapper.selectAnotherThing());
이 경우:
첫 번째 쿼리에서 사용된 커넥션이 반환된 후,
- 두 번째 쿼리에서 새 커넥션이 할당되는 구조인지,
- 아니면 두 번째 read가 끝날 때까지 첫 번째 커넥션도 유지되는지?
이 궁금증에 대한 답을 정리합니다.
결론 요약
항목 | 설명 |
---|---|
TransactionTemplate.read(...) 호출마다 트랜잭션 생성됨 | |
각 트랜잭션은 독립적인 커넥션 사용 | |
첫 번째 호출이 끝난 시점에 커넥션 반환되는가 | |
두 번째 호출 시 새 커넥션을 할당받는가 | |
NegSlaveTransactionSupport 컴포넌트가 상태 공유하거나 유지하는가 |
커넥션 흐름 구조
[ Tasklet 실행 ]
↓
read #1 → 트랜잭션 시작 → 쿼리 실행 → 트랜잭션 종료 → 커넥션 반환
↓
read #2 → 트랜잭션 시작 → 쿼리 실행 → 트랜잭션 종료 → 커넥션 반환
주요 포인트
TransactionTemplate
은 매 호출마다 트랜잭션을 새로 시작하고 종료- 내부적으로
PlatformTransactionManager
가 커넥션을 할당 및 반환 @Component
형태의NegSlaveTransactionSupport
는 상태를 공유하지 않으며 안전함- 커넥션 누수나 중첩 점유 없이 안정적 실행 가능
실전 예제
log.info("쿼리1 실행 시작");
slaveTxSupport.read(() -> slaveMapper.selectFirst());
log.info("쿼리2 실행 시작");
slaveTxSupport.read(() -> slaveMapper.selectSecond());
두 번째 쿼리가 실행되기 전에 첫 번째 쿼리의 커넥션은 반환됨
결론
Spring Batch의 Tasklet 안에서 TransactionTemplate
을 이용해 slave DB를 여러 번 호출할 경우,
각 호출은 독립된 트랜잭션으로 수행되며, 커넥션은 read()
블록 종료 시점에 즉시 반환됩니다.
컴포넌트가 상태를 공유하거나 커넥션을 유지하지 않으므로, 복수 호출 시에도 커넥션 누수 없이 안전하게 동작합니다.