운영 환경에서 배치 작업은
“하루의 마지막 프로세스이자, 다음 날의 시작점”이다.
그만큼 안정성이 중요하다.
하지만 시스템이 아무리 견고해도
실패하지 않는 배치는 없다.
진짜 중요한 건 실패가 아니라,
**“실패 이후 어떻게 복구할 것인가”**다.
1. 장애의 본질 — 데이터 정합성의 붕괴
배치 장애는 대부분 데이터 불일치에서 시작된다.
예를 들어보자.
보험 청구 배치에서 1,000건 중 843번째 처리 중 DB 세션이 끊겼다면,
1~842번은 커밋되었고,
843번 이후는 반영되지 않는다.
이 상태에서 단순히 배치를 재실행하면?
→ 중복 처리, 무결성 위반, 누락 발생.
**장애 대응의 본질은 ‘데이터 정합성 복구’**다.
2. 배치의 3단계 롤백 전략
| 단계 | 설명 | 예시 |
|---|---|---|
| 1단계: 트랜잭션 롤백 | 단일 트랜잭션 내 오류 시 rollback 처리 | DB commit 이전 오류 |
| 2단계: 청크 단위 복원 | 처리 단위(Chunk/ItemWriter)별 rollback 정책 설정 | Spring Batch의 SkipListener 활용 |
| 3단계: 업무 단위 재처리 | 전체 Job 재실행 대신 오류 데이터만 재처리 | 예외 테이블 기반 재처리 |
3. 재처리를 위한 설계 패턴
운영에서는 “다시 돌리면 된다”는 말이 가장 위험하다.
재처리를 하려면 반드시 재처리 가능한 구조여야 한다.
(1) 재처리 테이블 설계 예시
CREATE TABLE TB_JOB_ERROR_LOG (
JOB_ID VARCHAR(30),
STEP_ID VARCHAR(30),
DATA_KEY VARCHAR(50),
ERROR_MSG VARCHAR(500),
STATUS CHAR(1) DEFAULT 'E', -- E: Error, R: Reprocessed, C: Cleared
REG_DTM TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
→ 오류 발생 시 데이터를 로그 테이블에 적재.
→ 운영자는 이 테이블 기반으로 부분 재처리(JobRerun) 수행.
(2) 재처리 Job 호출 예시 (Java/Pseudo)
List<String> errorKeys = jobErrorDAO.findErrorKeys("PAAplyExprOBDentalLDAO");
for(String key : errorKeys) {
processSingleRecord(key);
jobErrorDAO.updateStatus(key, "R");
}
→ 이 구조를 만들어두면 “장애 Job 전체 재실행” 대신
문제 데이터만 추출·복구 가능하다.
4. 커밋 단위 조정은 예방의 핵심
배치 장애의 대부분은
커밋 단위가 너무 크거나, 너무 작아서 발생한다.
- 너무 크면 → 장애 시 rollback 범위 과도
- 너무 작으면 → DB I/O 증가, 처리 속도 저하
💡 실무 팁:
- 하루 1만 건 이하: 100건 단위 커밋
- 대용량(50만 건 이상): 500~1000건 커밋
- DB I/O 부하 감지 시
commit-interval즉시 조정
Spring Batch 설정 예시:
<chunk reader="itemReader" writer="itemWriter" commit-interval="500"/>
5. 운영 환경에서의 장애 대응 시나리오
📍 Case 1: DB Lock으로 인한 장애
- 증상: 특정 Step에서 멈춤
- 대응: 문제 세션 확인 → Kill 후 재시작
- 예방: Lock Timeout 설정 + Deadlock Retry 로직 추가
📍 Case 2: File I/O 중간 실패
- 증상: Output 파일 incomplete
- 대응: 임시 파일(
.tmp) 생성 후 완료 시 rename → atomic write 보장
📍 Case 3: Downstream API Timeout
- 증상: 외부 전송 실패
- 대응:
RetryTemplate적용 + 실패 데이터 큐잉 후 재처리 - 예방: Batch 내부에서 Timeout 재시도 금지 → 비동기 재처리로 분리
6. 모니터링 — ‘조기 탐지’가 복구보다 싸다
운영에서 가장 무서운 건 “늦게 발견된 장애”다.
- 로그 레벨별 수집 → ELK, CloudWatch, Grafana
- 배치 완료 여부 모니터링 → 결과 테이블 or 알림톡 자동화
예시:
SELECT JOB_ID, STATUS, END_TIME
FROM TB_BATCH_LOG
WHERE END_TIME IS NULL
AND START_TIME < SYSDATE - INTERVAL '1' HOUR;
→ 실행 완료되지 않은 Job 자동 감지
7. 재처리보다 더 중요한 것 — 사전 점검
- Input 파일 검증
- 외부 연계 API 사전 ping
- DB 커넥션 풀 상태 체크
- 예상 데이터 건수 미리 로깅
운영은 **“코드를 잘 짜는 일”보다
“예상 가능한 실패를 막는 일”**이다.
마치며
운영 배치의 품질은 장애 시점이 아니라,
복구까지 걸린 시간으로 평가된다.
그리고 그 속도는 운이 아니라 설계의 결과다.
“재처리는 코드를 고치는 게 아니라,
시스템을 회복시키는 기술이다.”