[Spring Batch] 건너뛰기

유기훈·2025년 6월 22일

건너뛰기(skip)

건너뛰기(skip)는 Spring Batch에서 특정 예외가 발생했을 때 해당 데이터만 무시하고 다음 아이템을 계속 처리하도록 하는 기능입니다.

  • 배치 처리를 중단하지 않고 예외가 발생한 아이템만 제외함
  • ItemReader, ItemProcessor, ItemWriter 중 어느 단계에서든 발생한 예외에 대해 건너뛰기 설정 가능
  • StepBuilder에서 .skip(Exception.class)과 .skipLimit(n)으로 설정

언제 사용해야 하나?

  • 데이터 오류가 빈번하지만 전체 배치를 멈추고 싶지 않은 경우
  • 일부 품질이 낮은 데이터는 무시해도 되는 경우
  • 외부 시스템과의 연동 실패가 간헐적이고, 이후 처리에는 영향이 없을 때
  • 로그로 기록만 하고 계속 진행하고 싶은 경우

Skip 설정 방법

@Bean
public Step skipStep() {
    return stepBuilderFactory.get("skipStep")
        .<String, String>chunk(10)
        .reader(itemReader())
        .processor(itemProcessor())
        .writer(itemWriter())
        .faultTolerant()
        .skip(ParsingException.class)
        .skipLimit(5)
        .build();
}
  • ParsingException: 발생 시 건너뛰는 예외
  • skipLimit(5): 총 5번까지만 예외를 허용. 초과하면 Step 실패

각 단계별 Skip 처리 방식

ItemReader의 Skip 처리

  • read() 메서드에서 예외가 발생할 경우 해당 예외가 skip 대상이면 해당 아이템을 무시하고 다음 아이템으로 이동
  • 단, Reader는 데이터를 읽기만 하고 상태를 유지하므로 read 위치를 잘 관리해야 함

예시 코드

public class SkipReader implements ItemReader<String> {
    private Iterator<String> data = List.of("item1", "error", "item2").iterator();

    @Override
    public String read() throws Exception {
        String item = data.next();
        if (item.equals("error")) {
            throw new ParsingException("Invalid format");
        }
        return item;
    }
}

ItemProcessor의 Skip 처리

  • process(item)에서 예외 발생 시 해당 아이템만 건너뜀
  • 다음 단계(ItemWriter)에는 전달되지 않음
  • 건너뛴 이유와 건수는 SkipListener 등을 통해 추적 가능

예시 코드

public class SkipProcessor implements ItemProcessor<String, String> {
    @Override
    public String process(String item) throws Exception {
        if (item.equals("bad")) {
            throw new IllegalStateException("Invalid data");
        }
        return item.toUpperCase();
    }
}
  • "bad" → 예외 발생 → skip 대상이면 무시됨, writer에 전달되지 않음

ItemWriter의 Skip 처리

  • write(List<? extends T> items) 전체에 대해 예외 발생 시 skip 처리
  • 일반적으로 어떤 아이템이 실패했는지 파악하기 어려움 → 개별 아이템 단위로 예외 추적 필요
  • FaultTolerantStepBuilder가 자동으로 chunk 재분할하여 실패 아이템을 찾고 skip 처리

예시 코드

public class SkipWriter implements ItemWriter<String> {
    @Override
    public void write(List<? extends String> items) throws Exception {
        for (String item : items) {
            if (item.equals("fail")) {
                throw new WriteFailureException("DB insert error");
            }
        }
        System.out.println("Written: " + items);
    }
}

Skip 처리 시 주의사항

  • skipLimit: 총 skip 가능한 횟수 제한 (초과 시 Step 실패)
  • noSkip(): 예외를 반드시 실패로 처리하고 싶을 때 사용
  • SkipListener: 어떤 아이템이 건너뛰어졌는지 로깅/후처리 가능
  • 상태 저장: skip이 발생해도 ExecutionContext에 상태 저장됨
profile
개발 블로그

0개의 댓글