728x90
반응형
SMALL

Step을 구현할 때 구현 방법에는 크게 Tasklet 방식이 있고 Chunk 방식이 있다. 아래 그림을 보자.

  • Step 1Tasklet으로 구현했고, Step 2Chunk 방식으로 구현했음을 알 수 있다.

그럼 Tasklet은 무엇일까?

 

Tasklet

Step을 구현하는 방법 중 하나인 TaskletChunk보다 단순한 방식으로 단일 작업을 구현한다. 아래는 Taskletinterface이다. execute를 구현해야 함을 알 수 있다.

@FunctionalInterface
public interface Tasklet {
    @Nullable
    RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception;
}

 

StepBuilderStep을 만들때, tasklet()안에다가 구현한 Tasklet을 넣어주면 된다. 아래 예시의 경우에는 sampleStep은 넣어준 sampleTasklet으로 동작하게 된다.

@Bean
@JobScope
public Step sampleStep(JobRepository jobRepository, PlatformTransactionManager platformTransactionManager) {
    return new StepBuilder("sampleStep", jobRepository)
            .tasklet(sampleTasklet(), platformTransactionManager)
            .build();
}

 

그럼 sampleTasklet은 어떻게 생겼을까? 아래 예시를 보자. 

@Bean
@StepScope
public Tasklet sampleTasklet() {
	return (contribution, chunkContext) -> {
    	log.info("never ending tasklet");
        return RepeatStatus.CONTINUABLE:
    }
}

@Bean
@StepScope
public Tasklet sampleTasklet() {
	return (contribution, chunkContext) -> {
    	log.info("finish");
        return RepeatStatus.FINISHED:
    }
}
  • 두 가지 예시를 가져와봤다. Tasklet의 상태는 계속 진행할지, 끝낼지 두가지로만 표현된다.
  • RepeatStatus.FINISHED가 반환되면 tasklet이 바로 끝나고, RepeatStatus.CONTINUABLE이 반환되면, Tasklet을 다시 실행한다. 따라서, RepeatStatus.CONTINUABLE을 반환한 예시는 영구적으로 끝나지 않고 계속해서 로그를 남기게 된다.
  • 참고로, null을 반환하면 FINISHED와 동일하게 동작한다.

 

Tasklet을 만들 때 주의할 점

@Bean
@StepScope
public Tasklet hugeReadTasklet(PriceRepository priceRepository) {
    return (contribution, chunkContext) -> {
        List<Price> prices = priceRepository.findByDate(LocalDateTime.now());
        prices.forEach(price -> price.setAmount(0L));
        priceRepository.saveAll(prices);
        return RepeatStatus.FINISHED;
    };
}
  • 이 코드는 문제가 발생할 수 있는 포인트가 있다.
  • PriceRepository.findByDate()를 통해서 얼마나 많은 데이터를 가져올지 예측이 불가하다. 데이터가 너무 많다면 천만개의 데이터를 조회할 수도 있다. 천만개의 데이터를 한번에 가져온다면 메모리 이슈로 인해 처리가 불가해지고 OOM이 발생할 수 있다.
  • Tasklet 형식의 SteptransactionManager를 추가하게 되면 해당 TaskletTransaction에 묶이게 된다. 이때 Tasklet에서 너무 많은 데이터를 불러오고 쓰게 되면, TaskletTransaction은 너무 거대해진다. 그 말은 DatabaseTransaction 1개가 처리해야 할 일이 너무 많아지게 된다고도 할 수 있다.

 

이런 문제를 해결하기 위해, Chunk Processing을 사용하게 된다. Step을 구현하는 방법 중 대표적인 방법 하나인 Chunk Processing.

 

정리를 하자면

Tasklet에 대해 알아보았다. 간단한 스텝을 구현할 땐 유용하게 사용할 수 있지만, 조금 복잡하거나 처리할 데이터의 양이 많아지고 예측할 수 없다면 주의해야 한다. 그래서 이럴땐 Chunk Processing을 사용하면 된다. 다음 포스팅에서 알아보자!

728x90
반응형
LIST

'Spring Batch' 카테고리의 다른 글

ItemReader  (1) 2024.10.09
Chunk Processing  (5) 2024.10.09
Step  (2) 2024.10.09
Job  (7) 2024.10.09
Spring Batch 구조와 핵심 키워드  (2) 2024.10.09

+ Recent posts