📋 개요
대용량 Excel 데이터(30,000건 이상) 처리 시 발생하던 OutOfMemory (OOM) 문제를 해결하기 위해 BatchInsertExecutor 유틸리티 클래스를 도입하여 메모리 효율적인 bulk insert를 구현했습니다.
🔴 문제 상황
발생한 문제
- OOM 발생: 30,000건의 Excel 데이터 처리 시
-jvmXmx=1024 환경에서 OutOfMemory 발생
- 높은 메모리 사용량:
excelOrderCustomerMapper.insertExcelOrdersBatch 호출 시 약 2.69GB 메모리 사용
- ExecutorType.SIMPLE 사용 시: 약 3.4GB 메모리 사용
- ExecutorType.BATCH 사용 시: 약 390MB 메모리 사용 (약 88% 감소)
원인 분석
- 대량 데이터 일괄 처리: 한 번에 수만 건의 데이터를 insert하려고 시도
- 암호화 함수 사용:
AES_ENCRYPT 함수로 인한 쿼리 문자열 크기 증가
- 각 행마다 암호화된 문자열이 preparedStatement에 포함
- 30,000건 × 큰 쿼리 문자열 = 엄청난 메모리 사용량
- MyBatis preparedStatement 메모리 누적:
- ExecutorType.BATCH: preparedStatement를 메모리에 쌓아두고
flushStatements() 호출 시 DB로 전송
- 문제: 30,000건을 한 번에 처리하면 모든 preparedStatement가 메모리에 누적
- 결과: 메모리 사용량 피크가 매우 높아져 OOM 발생
- useGeneratedKeys와 ExecutorType.BATCH 호환성 문제:
useGeneratedKeys="true" 사용 시 BATCH 모드에서 UnsupportedOperationException 발생
- GC 비효율: 큰 객체들이 Old Generation으로 이동하여 GC 효율성 저하
✅ 해결 방안
1. BatchInsertExecutor 유틸리티 클래스 도입
핵심 아이디어:
- 작은 배치 단위(기본 1000건)로 데이터를 분할하여 처리
ExecutorType.BATCH와 flushStatements()를 활용하여 메모리 효율적인 insert
useGeneratedKeys 필요 여부에 따라 ExecutorType.SIMPLE 또는 BATCH 자동 선택