Spring Batch - 03. Job

출처

목차

Job 이란

Batch 계층 구조에서 가장 상위에 있는 개념으로 하나의 Batch 작업 자체를 의미한다.

  • Job Configuration 을 통해 생성되는 객체 단위로서 Batch 작업을 어떻게 구성하고 실행할지를 명세해 놓은 객체
  • Batch Job 을 구성하기 위한 최상위 인터페이스며 Spring Batch 가 기본 구현체를 제공한다.
  • 여러 Step 을 포함하는 컨테이너로서 반드시 한개 이상의 Step 으로 구성돼야 한다.

Spring Batch에서 Job은 하나 이상의 Step으로 구성된 일련의 작업 흐름을 정의하는 개념입니다. Job은 일괄 처리 작업의 논리적인 단위이며, 배치 작업을 실행하는데 필요한 모든 정보를 포함합니다.

Job은 일괄 처리 작업을 실행하는데 필요한 다양한 설정을 제공합니다. 예를 들어, Job은 어떤 Step이 실행되어야 하는지, 어떤 파라미터를 사용해야 하는지, 어떤 예외 상황에 대처해야 하는지 등의 정보를 포함합니다. 또한 Job은 실행 순서, 종료 조건, 중지/재시작 가능 여부 등의 작업 흐름을 제어하는 데 사용됩니다.

Spring Batch에서 Job은 JobBuilderFactory를 사용하여 생성됩니다. JobBuilderFactory는 JobBuilder 객체를 생성하고, 이를 사용하여 Job을 구성합니다. JobBuilder 객체를 사용하여 Job의 이름, 작업 수행에 필요한 Step, 파라미터 등을 정의할 수 있습니다.

Spring Batch에서 Job은 JobRepository에 저장됩니다. JobRepository는 Job의 실행 상태, 실행 시간 등의 정보를 관리하고, 작업이 성공적으로 완료되었는지, 실패했는지 등의 상태를 추적합니다.

Spring Batch에서 Job은 JobLauncher를 사용하여 실행됩니다. JobLauncher는 JobRepository를 사용하여 Job을 실행하고, 실행 결과를 반환합니다. Job을 실행할 때는 JobParameters를 전달하여 Job을 구성할 수 있습니다.

Spring Batch에서 Job은 대규모 데이터 처리 작업을 일괄적으로 처리하는데 사용되며, 작업의 실행, 모니터링, 실패한 작업 처리, 작업 재시작 등의 기능을 제공합니다.

Job 의 구성

하나의 Job은 여러개의 Step 으로 구성돼 있고, 하나의 Step 내에서는 여러개의 tasklet 을 가질 수 있다.

Job은 단일 작업 또는 여러 단계 작업을 수행할 수 있으며, 각 단계는 하나 이상의 스텝으로 구성됩니다. 예를 들어, 데이터베이스에서 데이터를 추출하고 가공한 후 결과를 다시 데이터베이스에 로드하는 작업을 정의할 수 있습니다. 이러한 작업은 여러 스텝으로 구성될 수 있습니다. 첫 번째 스텝은 데이터베이스에서 데이터를 추출하는 것이며, 두 번째 스텝은 추출된 데이터를 처리하는 것이며, 마지막 스텝은 처리된 데이터를 데이터베이스에 로드하는 것입니다.

Job 인터페이스

public interface Job {

String getName();

boolean isRestartable();

void execute(JobExecution execution);

@Nullable
JobParametersIncrementer getJobParametersIncrementer();

JobParametersValidator getJobParametersValidator();
}

Spring Batch Job 기본 구현체

Spring Batch 는 대표적인 Job 의 구현체로 SimpleJob 과 FlowJob 을 제공합니다.

  • SimpleJob
    • 순차적 으로 Step 을 실행시키는 Job
    • 모든 Job 에서 사용할 수 있는 표준 기능을 가지고 있다.
  • FlowJob
    • 특정한 조건흐름 에 따라 Step 을 구성해 실행시키는 Job
    • Flow 객체를 실행시켜서 작업을 진행한다.

코드 예시

@Configuration
@RequiredArgsConstructor
@Slf4j
public class HelloJobConfiguration {

private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;

@Bean
public Job helloJob() {
return jobBuilderFactory.get("Hello Job")
.start(helloStep1())
.next(helloStep2())
.build();
}

public Step helloStep1() {
return stepBuilderFactory.get("Hello Step1")
.tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
log.info(" ========================");
log.info(" >> Hello Spring Batch!!");
log.info(" ========================");
return RepeatStatus.FINISHED;
}
}
).build();
}

public Step helloStep2() {
return stepBuilderFactory.get("Hello Step2")
.tasklet((contribution, chunkContext) -> {
log.info(" ========================");
log.info(" >> Hello Spring Batch2!!");
log.info(" ========================");
return RepeatStatus.FINISHED;
}).build();
}
}

BatchAutoConfiguration

BatchAutoConfiguration 에서는 JobLauncherApplicationRunner 를 이용해 Job 을 실행 시킨다.

BatchAutoConfiguration.java

public JobLauncherApplicationRunner jobLauncherApplicationRunner(JobLauncher jobLauncher, JobExplorer jobExplorer, JobRepository jobRepository, BatchProperties properties) {
JobLauncherApplicationRunner runner = new JobLauncherApplicationRunner(jobLauncher, jobExplorer, jobRepository);
String jobNames = properties.getJob().getNames();
if (StringUtils.hasText(jobNames)) {
runner.setJobNames(jobNames);
}

return runner;
}

JobLauncherApplicationRunner

JobLauncherApplicationRunner 는 JobLauncher 객체를 이용해 Job 과 Parameter 를 받아 Job 을 실행시킨다.

JobLauncherApplicationRunner

protected void execute(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException, JobParametersNotFoundException {
JobParameters parameters = this.getNextJobParameters(job, jobParameters);
JobExecution execution = this.jobLauncher.run(job, parameters);
if (this.publisher != null) {
this.publisher.publishEvent(new JobExecutionEvent(execution));
}

}
Share