[Spring Batch] Tasklet와 Chunk

AIR·2025년 2월 2일

Spring Batch


배치는 대량의 데이터를 일괄적으로 처리하는 방식을 의미한다. 일반적으로 실시간 처리와 달리 특정 시간에 정해진 작업들을 모아서 처리한다. 예를 들어 매일 자정에 고객 데이터 정산, 로그 분석, 청구서 생성 등이 배치 작업에 해당한다.

Spring Batch는 배치 작업을 효율적으로 개발하고 관리하도록 도와주는 프레임워크이다. Job은 '읽기->처리->쓰기' 과정을 정의한 배치 작업 단위이며, 하나의 배치 Job은 여러 개의 Step으로 구성될 수 있다.

Step은 Job 내부의 실제 작업 단위이며, Step은 Tasklet 또는 Chunk 기반 작업을 수행한다.


Tasklet


Tasklet은 단일 작업을 수행하는 단순한 인터페이스이다. 반복적인 데이터 처리에는 적합하지 않으며 단순 파일 삭제와 같은 작업을 할때 사용한다.

Tasklet은 execute 메서드로 실제 작업을 수행하는데, RepeatStatus 값을 반환하여 작업의 반복 여부를 결정한다.

  • RepeatStatus.FINISHED: 작업이 완료되어 더 이상 반복하지 않음
  • RepeatStatus.CONTINUABLE: 작업을 계속 반복 실행해야 함
@Bean
public Job sampleJob() {
    return jobBuilderFactory.get("sampleJob")
            .start(step1())
            .next(step2())
            .build();
}

@Bean
public Step step1() {
    return stepBuilderFactory.get("step1")
            .tasklet((contribution, chunkContext) -> {
                System.out.println("Step 1 수행 중...");
                return RepeatStatus.FINISHED;
            })
            .build();
}

@Bean
public Step step2() {
    return stepBuilderFactory.get("step2")
            .tasklet((contribution, chunkContext) -> {
                System.out.println("Step 2 수행 중...");
                return RepeatStatus.FINISHED;
            })
            .build();
}

Chunk


Chunk란 각 커밋 사이에 처리되는 row 수를 뜻한다. Chunk 방식 처리는 데이터를 Chunk 단위로 나누어 읽기, 처리, 쓰기를 반복하는 구조이며 Chunk 단위로 트랜잭션을 다룬다. 대용량 데이터 처리에 적합하며, 반복 작업에 유리하다.

@Bean
public Step chunkStep() {
    return stepBuilderFactory.get("chunkStep")
            .<String, String>chunk(10)
            .reader(itemReader())
            .processor(itemProcessor())
            .writer(itemWriter())
            .build();
}

@Bean
public ItemReader<String> itemReader() {
    return new ListItemReader<>(List.of("item1", "item2", "item3"));
}

@Bean
public ItemProcessor<String, String> itemProcessor() {
    return item -> "Processed " + item;
}

@Bean
public ItemWriter<String> itemWriter() {
    return items -> items.forEach(System.out::println);
}

ItemReader

ItemReader는 외부 데이터 소스로부터 데이터를 읽어온다. 이때 데이터 소스는 데이터베이스, File, JSON 등 다앙햔 유형을 지원한다. 또한 사용자가 Custom Reader 구현체를 만들 수도 있다.

주요 구현체

  • JdbcCursorItemReader: DB 커서 기반 읽기
  • FlatFileItemReader: CSV, TXT 파일 읽기
  • JpaPagingItemReader: JPA 기반 데이터 읽기
  • StaxEventItemReader: XML 파일 읽기

CSV 파일에서 데이터를 읽기

@Bean
public FlatFileItemReader<Person> reader() {
    return new FlatFileItemReaderBuilder<Person>()
        .name("personItemReader")
        .resource(new ClassPathResource("people.csv"))
        .delimited()
        .names("firstName", "lastName")
        .targetType(Person.class)
        .build();
}

ItemProcessor

ItemProcessor은 데이터를 가공하거나 필터링하는 단계이다. Processor는 필수가 아니며, Reader와 Writer와는 별도의 단계로 비즈니스 로직을 추가할 때 사용한다.

ItemReader가 반환한 데이터 객체를 받아서 데이터를 가공하게 된다.

이름을 대문자로 변환

@Bean
public ItemProcessor<Person, Person> processor() {
    return person -> {
        person.setFirstName(person.getFirstName().toUpperCase());
        person.setLastName(person.getLastName().toUpperCase());
        return person;
    };
}

ItemWriter

ItemWriter는 Reader와 Processor를 거쳐 가공된 데이터를 최종적으로 저장하는 단계이다. 가공된 데이터 리스트를 입력받는데, Reader와 Processor에서 처리된 Item은 Chunk 단위만큼 쌓은 뒤 Writer에 전달된다.

주요 구현체:

  • JdbcBatchItemWriter: DB에 배치로 저장
  • JpaItemWriter: JPA를 사용한 저장
  • FlatFileItemWriter: 파일로 저장
  • CompositeItemWriter: 여러 대상에 동시에 저장 가능

데이터베이스에 저장 (JPA)

@Bean
public JpaItemWriter<Person> writer(EntityManagerFactory entityManagerFactory) {
    JpaItemWriter<Person> writer = new JpaItemWriter<>();
    writer.setEntityManagerFactory(entityManagerFactory);
    return writer;
}

참고

https://jojoldu.tistory.com/331
https://jojoldu.tistory.com/336
https://jojoldu.tistory.com/339
https://jojoldu.tistory.com/347

profile
백엔드

0개의 댓글