1. Spring Batch 재시도 로직의 필요성
- Spring Batch에서 Step을 실행하는 동안 다양한 예외가 발생할 수 있습니다.
- 모든 예외가 치명적인 것은 아니며, 일부는 재시도를 통해 성공할 수 있습니다.
- 예외의 성격에 따라 적절한 처리 방식을 선택하는 것이 중요합니다.
1.1 예외 유형별 처리 방식
- 예외를 크게 두 가지 유형으로 분류할 수 있습니다
- 결정적 예외(Deterministic Exception): 재시도해도 같은 결과가 나오는 예외
- 비결정적 예외(Non-deterministic Exception): 재시도하면 성공할 가능성이 있는 예외
1.1.1 결정적 예외의 예시
FlatFileParseException
: 파일 읽기 중 발생하는 파싱 오류- 동일한 레코드에 대해 항상 같은 예외가 발생합니다.
- ItemReader를 재설정해도 해결되지 않습니다.
- 이런 경우에는 Skip 처리나 Step 실패로 처리하는 것이 적절합니다.
1.1.2 비결정적 예외의 예시
DeadlockLoserDataAccessException
과 같이 잠시 기다린 후 재시도하면 성공할 가능성이 있는 예외가 있습니다.DeadlockLoserDataAccessException
은 데이터베이스 데드락으로 인한 예외입니다.- 현재 프로세스가 다른 프로세스가 잠금을 보유한 레코드를 업데이트하려 할 때 발생합니다.
- 이러한 비결정적 예외의 경우에는 재시도 로직을 적용하는 것이 효과적입니다.
재시도 대상 예외 선정 기준
재시도 대상 예외를 선정할 때는 다음 기준을 고려해야 합니다:
- 일시적인 네트워크 문제로 인한 예외
- 동시성 제어로 인한 데이터베이스 예외
- 외부 시스템의 일시적 장애로 인한 예외
2. 재시도 로직 설정 방법
2.1 기본 재시도 설정
- Spring Batch에서 재시도 로직을 설정하는 방법은 다음과 같습니다.
2.1.1 Java Configuration 방식
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("step1", jobRepository)
.<String, String>chunk(2, transactionManager)
.reader(itemReader())
.writer(itemWriter())
.faultTolerant()
.retryLimit(3)
.retry(DeadlockLoserDataAccessException.class)
.build();
}
- 이 설정에서 각 옵션의 의미는 다음과 같습니다
faultTolerant()
: 오류 허용 모드를 활성화합니다.retryLimit(3)
: 개별 아이템에 대해 최대 3번까지 재시도를 허용합니다.retry(DeadlockLoserDataAccessException.class)
: 지정된 예외에 대해서만 재시도를 수행합니다.
2.2 다중 예외 타입 지원
- 여러 종류의 예외에 대해 재시도를 적용하고 싶다면 다음과 같이 설정할 수 있습니다.
2.2.1 여러 예외 타입 설정
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("step1", jobRepository)
.<String, String>chunk(2, transactionManager)
.reader(itemReader())
.writer(itemWriter())
.faultTolerant()
.retryLimit(3)
.retry(DeadlockLoserDataAccessException.class)
.retry(OptimisticLockingFailureException.class)
.retry(TransientDataAccessException.class)
.build();
}