
백엔드
그날, 우리의 배치는 왜 멈추었을까?
두줄요약
Spring Batch 배치가 멈춘 원인을 트랜잭션 분리 실패와 스레드 풀 정책에서 찾았습니다. `CallerRunsPolicy`와 `@Transactional` 누락이 겹치며 경합이 발생했고, 설정 개선이 필요했습니다.
문제 상황
- Spring Batch Tasklet 기반 배치가 종료되지 않고 정지
- 특정 데이터 업데이트 이후 로그가 멈추고, DB 데드락과 lock wait 의심
- 멀티스레드 병렬 처리와 주문 관련 빈번한 업데이트로 시스템 부하 발생
원인 분석
- 서비스 메소드의
@Transactional누락으로 트랜잭션 경계 분리 실패 TransactionSynchronizationManager의 스레드 로컬 특성으로 스레드별 독립 트랜잭션 형성ThreadPoolExecutor의CallerRunsPolicy로 메인 스레드가 작업을 직접 수행하며 경합 발생
해결 방법
- 서비스 메소드에
Propagation.REQUIRES_NEW로 트랜잭션 분리 RejectedExecutionHandler정책 재검토 및 스레드/큐 설정 조정- 메인 스레드와 작업 스레드 간 커밋 대기 루프 방지
