실패한 Spring Batch 작업을 복구할 때는 어떤 인스턴스의 어느 실행이 실패했는지부터 확인해야 합니다. JobInstance는 작업의 식별 단위이고, JobExecution은 실행 시도, StepExecution은 그 시도 안에서 실제 실행한 Step의 기록입니다.
아래 SQL은 Spring Batch 기본 JDBC 메타데이터 테이블을 읽는 예제입니다. 테이블 접두사를 바꿨다면 이름을 맞추고, 조회 전용 계정으로 실행하세요. Java 설정은 Spring Batch 5.2 API 기준이며 실제 운영 시스템을 실행한 결과는 아닙니다.
이 글에서 바로 찾기 5개 항목
Job 이름은 BATCH_JOB_INSTANCE에 있습니다
BATCH_JOB_EXECUTION에는 JOB_NAME이 없습니다. 인스턴스 테이블과 조인해야 특정 Job의 실행 기록을 찾을 수 있습니다. 아래 이름은 자신의 Job 이름으로 바꾸세요.
SELECT i.JOB_NAME,
e.JOB_INSTANCE_ID,
e.JOB_EXECUTION_ID,
e.STATUS,
e.START_TIME,
e.END_TIME,
e.EXIT_CODE,
e.EXIT_MESSAGE
FROM BATCH_JOB_INSTANCE i
JOIN BATCH_JOB_EXECUTION e
ON e.JOB_INSTANCE_ID = i.JOB_INSTANCE_ID
WHERE i.JOB_NAME = 'dailyReportJob'
ORDER BY e.JOB_EXECUTION_ID DESC;
여러 실행이 있다면 최근 행만 무조건 선택하지 마세요. 인스턴스 ID와 업무 기준일을 함께 대조해야 다른 날짜의 작업을 복구하는 실수를 막을 수 있습니다. 파라미터 저장 구조는 버전별로 차이가 있으므로 공식 메타데이터 스키마와 설치한 버전의 DDL을 확인합니다.
실패한 실행 ID로 Step 기록을 좁힙니다
SELECT STEP_EXECUTION_ID,
STEP_NAME,
STATUS,
READ_COUNT,
WRITE_COUNT,
FILTER_COUNT,
COMMIT_COUNT,
ROLLBACK_COUNT,
EXIT_MESSAGE
FROM BATCH_STEP_EXECUTION
WHERE JOB_EXECUTION_ID = 12345
ORDER BY STEP_EXECUTION_ID;
12345는 앞에서 확인한 실행 ID로 바꿉니다. Read Count와 Write Count가 다르다고 곧바로 누락이라고 판단하면 안 됩니다. 필터·스킵·재시도 정책이 영향을 주며, 외부 API나 파일의 결과가 메타데이터와 같은 트랜잭션에 묶여 있지 않을 수도 있습니다.
재시작은 이전 실행을 덮어쓰지 않습니다
| 확인한 상태 | 다음 판단 |
|---|---|
| FAILED / STOPPED | 실행 프로세스가 종료됐는지 확인한 뒤 재시작 허용 여부와 업무 부수 효과를 점검합니다. |
| COMPLETED | 같은 인스턴스를 재시작할 대상이 아닙니다. 재산출이 필요하면 별도 업무 절차로 구분합니다. |
| STARTED가 오래 유지됨 | 실제 프로세스·스케줄러·DB 세션을 확인합니다. 상태만 보고 곧바로 새 실행을 시작하지 않습니다. |
재시작 가능한 실패 인스턴스에 새 JobExecution이 만들어지면, 이미 완료한 Step은 기본적으로 다시 실행하지 않습니다. 다만 allowStartIfComplete(true)나 startLimit 설정, Reader의 상태 저장 여부에 따라 동작이 달라집니다. Step 재시작 설정 문서에서 각각의 조건을 확인하세요.
preventRestart(false)는 사용하지 않습니다
Spring Batch 5.2의 preventRestart()는 재시작을 금지하는 인자 없는 메서드입니다. 재시작을 허용하려면 일반적인 Job 구성에서 이 메서드를 호출하지 않습니다. 아래 메서드는 JobRepository와 두 Step이 이미 빈으로 구성되어 있다는 가정입니다.
@Bean
public Job dailyReportJob(JobRepository jobRepository,
Step importStep,
Step reportStep) {
return new JobBuilder("dailyReportJob", jobRepository)
.start(importStep)
.next(reportStep)
.build();
}
관련 타입은 org.springframework.batch.core.Job, Step, org.springframework.batch.core.job.builder.JobBuilder, org.springframework.batch.core.repository.JobRepository입니다. 메서드 정의는 JobBuilderHelper API에 나와 있습니다.
복구 완료는 상태값과 업무 결과를 함께 확인합니다
- 동일 작업을 자동으로 다시 요청하는 스케줄러가 있는지 확인합니다.
- 실패 원인과 외부 시스템의 처리 결과를 확인합니다. 응답을 받지 못했다고 실제 처리가 없었던 것은 아닙니다.
- 식별 파라미터를 유지하여 승인된 실행 경로로 재시작합니다.
- 이전·새 실행의 인스턴스 ID, Step 상태, 업무 결과 건수와 합계를 비교합니다.
- 재시작한 실행 ID와 판단 근거를 남깁니다. 메타데이터를 직접 삭제하거나 상태를 임의 수정하지 않습니다.
식별 파라미터를 바꾸면 다른 인스턴스가 될 수 있다는 점은 JobParameters 설계 예제에서 확인할 수 있습니다. 복구 중 외부 전송의 중복 가능성이 있다면 트랜잭션 롤백과 보상 처리의 차이부터 점검하세요.
복구의 성공 기준은 단순히 COMPLETED가 찍히는 것이 아닙니다. 올바른 대상의 작업을 이어갔고, 이미 처리한 데이터가 중복 반영되지 않았다는 근거가 남아야 합니다.