운영 배치 장애 대응 전략 — 재처리와 롤백 설계

배치가 중간에 실패했을 때 가장 위험한 대응은 처리 범위를 모르는 상태에서 다시 실행하는 것입니다. 먼저 이미 커밋된 데이터, 실패한 트랜잭션, 외부에 전달된 요청을 구분해야 합니다. DB 롤백과 업무 보상은 같은 작업이 아닙니다.

이 글에서 바로 찾기 7개 항목

843번째에서 실패해도 842건이 저장됐다고 단정할 수 없습니다

예를 들어 청크 크기가 100이고 1~800번까지 커밋된 뒤 다음 청크 처리 중 오류가 났다고 가정해 봅시다. 해당 청크가 하나의 DB 트랜잭션이고 그 트랜잭션 전체가 롤백됐다면, 커밋 경계는 800건일 수 있습니다. 처리 순번과 커밋 건수는 다릅니다.

이 숫자는 설명을 위한 가정입니다. 실제 결과는 트랜잭션 경계, 스킵·재시도, Writer 구현, 외부 시스템 처리 여부에 따라 달라집니다. 청크의 커밋 동작은 Spring Batch 커밋 간격 문서와 사용 중인 설정을 함께 확인해야 합니다.

복구 전에 세 영역을 나눠 확인합니다

영역확인할 근거와 대응
현재 DB 트랜잭션실제로 롤백됐는지 확인합니다. SkipListener 같은 콜백 자체가 롤백 전략을 대신하지는 않습니다.
이미 커밋된 업무 데이터재처리 시 유일 키·상태·합계가 어떻게 바뀌는지 확인합니다. 필요한 경우 승인된 보상 작업으로 정정합니다.
외부 API·파일·메시지DB 롤백만으로 취소되지 않을 수 있습니다. 상대 시스템 조회나 접수 ID로 결과를 확인한 뒤 재요청합니다.
광고

첫 조회는 변경 쿼리가 아닌 상태 확인입니다

다음은 Spring Batch 기본 메타데이터 테이블을 조회하는 SQL입니다. 자신의 Job 이름으로 바꾸고 읽기 전용 권한으로 실행하세요.

SELECT i.JOB_NAME, e.JOB_EXECUTION_ID, e.STATUS,
       e.START_TIME, e.END_TIME, e.EXIT_MESSAGE
FROM BATCH_JOB_INSTANCE i
JOIN BATCH_JOB_EXECUTION e
  ON i.JOB_INSTANCE_ID = e.JOB_INSTANCE_ID
WHERE i.JOB_NAME = 'dailySettlementJob'
ORDER BY e.JOB_EXECUTION_ID DESC;

이 조회만으로 업무 데이터의 정합성을 보장할 수는 없습니다. 실패 실행 ID를 찾은 뒤 StepExecution 조회와 복구 검증 절차에 따라 처리 기록을 좁히고, 업무 기준일별 원본 건수·결과 건수·합계를 대조하세요.

타임아웃은 실패 확정이 아닙니다

외부 결제·전송 API에서 응답을 받지 못했더라도 상대 시스템은 요청을 처리했을 수 있습니다. 무조건 재시도하면 같은 업무가 두 번 반영될 수 있습니다. API가 제공하는 조회 기능과 멱등 키 정책을 먼저 확인하세요.

설명용 처리 흐름
1. 업무 키로 기존 요청 기록 조회
2. 상대 시스템의 접수 결과 조회
3. 성공 확인 -> 내부 결과 대조 후 완료 처리
4. 미접수 확인 -> 서비스 계약에 맞는 동일 멱등 키로 재요청
5. 결과 불명 -> 자동 재시도 보류, 운영 확인 대상으로 분리

위 흐름은 특정 API의 실행 코드가 아닙니다. “실패 키 목록을 반복 처리하고 성공 표시”만 하는 코드에는 동시 실행 제어와 중복 처리 방지가 빠질 수 있으므로 그대로 운영에 넣으면 안 됩니다.

잠금·파일 오류도 무조건 종료하지 않습니다

  • DB 잠금: 대기 세션과 차단 세션, 진행 중인 업무를 확인합니다. 세션 종료는 다른 작업까지 롤백시킬 수 있으므로 담당자 승인과 복구 계획이 먼저입니다.
  • 파일 쓰기 실패: 임시 파일과 최종 파일을 분리하고 완료 후 검증합니다. 이름 변경의 원자성은 파일시스템·동일 볼륨 여부 등에 의존하므로 항상 보장된다고 가정하지 않습니다.
  • 공간 부족: 로그·임시 파일·결과 파일의 보존 기준을 확인합니다. 원본이나 장애 증거를 즉시 삭제하지 않습니다.
광고

커밋 크기는 데이터 건수만으로 정하지 않습니다

“1만 건이면 100, 50만 건이면 1,000”처럼 일률적인 값을 적용하지 마세요. 한 건의 크기와 처리 시간, 잠금 지속 시간, 메모리, 재처리 비용이 다릅니다. 테스트 환경에서 후보 크기별 처리 시간과 실패 복구 범위를 측정하고 운영 변경은 점진적으로 적용합니다.

재실행 승인 전에 남길 기록

  1. 실행 ID, 업무 대상, 오류 시각, 마지막 커밋 근거를 모읍니다.
  2. 스케줄러와 수동 실행이 겹치지 않도록 실행 주체를 정리합니다.
  3. 외부 시스템에 이미 반영된 요청이 있는지 확인합니다.
  4. 동일 인스턴스 재시작인지 별도 보상 작업인지 결정합니다.
  5. 처리 후 유일 키 중복, 누락, 건수·합계를 확인하고 결과를 기록합니다.

인스턴스 키를 바꾸면 복구가 아니라 새 실행이 될 수 있으므로 식별 JobParameters 설계를 함께 확인하세요. 장애의 시간 흐름이 불명확하다면 실행 ID로 로그를 좁히는 방법이 먼저입니다.

안전한 복구는 빠르게 다시 누르는 일이 아닙니다. 이미 끝난 일과 아직 끝나지 않은 일을 근거로 구분하고, 정합성을 확인할 수 있는 단위로 재실행하는 것입니다.

댓글 남기기

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