인프런 커뮤니티 질문&답변

아리마님의 프로필 이미지
아리마

작성한 질문수

스프링 배치

JobParametersIncrementer 문의드립니다.

작성

·

825

0

안녕하세요.
컨트롤러 만들어서 jobLauncher.run 으로 job 을 실행시키는 방식으로 개발 중에 있는데요.
 
컨트롤러 안에서 JobParameter 생성해서 run 의 인자로 셋팅을 했는데
이렇게 개발을 하니 강의대로 CustomJobParameterIncrementer 를 설정해도 Incrementer 가 적용되지 않는 거 같습니다.
 
Job 최초 실행 시, execution_params DB 테이블에 Incrementer 에서 생성한 파라미터가 기록되지도 않고
두번 실행하면 중복 오류가 발생하고 있고요.
 
확인 좀 부탁드립니다.

답변 4

1

정수원님의 프로필 이미지
정수원
지식공유자

Job 을 실행하는 주체가 스프링 배치에서 제공하는 JobLauncherApplicationRunner 를 통해 Job 을 자동으로 실행하는 것이 아닌 JobLauncherController 에서 직접 정의한 jobLauncher 를 통해서 하고 있다면 Job 에서  CustomJobParameterIncrementer 를 설정한 부분이 적용되지 않습니다.

즉 스프링 배치가 편의상 제공하는 Incrementer API 는 JobLauncherApplicationRunner 에서 컨트롤 하고 있는 것이며 만약 직접 jobLauncher 를 통해 Job 을 실행한다면  JobParameters 를 생성할 때 run.id 와 같은 구문을 직접 작성해야 합니다.

근데 위의 코드를 보면 

JobParameters jobParameters = new JobParametersBuilder()

.addLong("id", member.getId())

.addString("name", member.getName())

.toJobParameters();

이렇게 선언하고 있습니다.

JobParameters 에 저장하는 키와 값을 보면 "id" 와 "name" 이기 때문에 이 값은 Job 을 여러번 실행하더라도 동일한 값으로 저장될 것이기 때문에 중복오류가 발생하는 것입니다.

위 코드에

.addString("run.id", new Date()) 와 같은 구문을 추가해서 Job 이 실행될 때 마다 date 의 값이 다르게 저장되도록 하면 정상적으로 작동하게 됩니다.

한가지 기억하실 점은
jobLauncher.run(job, jobParameters);

으로 실행한 이후에는 더 이상 jobParameters 값을 변경하거나 추가할 수 없고 그 전에 jobParameters 의 설정이 다 마쳐져야 하는데 스프링 배치에서 제공하는 JobLauncherApplicationRunner 에서는 우리가 직접 설정한 CustomJobParameterIncrementer 값을 받아서 기존의 jobParameters 항목에다 추가해서 jobLauncher.run(job, jobParameters) 를 실행하고 있다고 보시면 됩니다.

그렇기 때문에 우리가 직접 jobLauncher 를 컨트롤 해서 실행한다면 Job 의 Incrementer API 는 적용되지 않기 때문에 jobParameters 를 생성할 때 .addString("run.id", new Date()) 처럼 Incrementer 의 로직을 수행하도록 항목을 세팅하시면 됩니다.

 

 

0

아리마님의 프로필 이미지
아리마
질문자

강의 내용에 위와 같은 설명이 없어서 이해를 못하고 있었습니다.

상세하게 설명을 해주셔서 잘 이해했습니다. 감사합니다.

0

아리마님의 프로필 이미지
아리마
질문자

JobLauncher 강의 설명하실 때, 작성하신 비동기식 동작 소스를 그대로 활용했습니다..

Job 은 강사님 소스와 완전 동일하고요..

 

@RestController

@RequiredArgsConstructor

public class JobLauncherController {

private final Job job;

private final BasicBatchConfigurer basicBatchConfigurer;

 

@PostMapping("/execute")

public String executeJob(@RequestBody Member member) throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException {

JobParameters jobParameters = new JobParametersBuilder()

.addLong("id", member.getId())

.addString("name", member.getName())

.toJobParameters();

// 비동기식으로 Job수행 처리를 위한 설정

SimpleJobLauncher jobLauncher = (SimpleJobLauncher)basicBatchConfigurer.getJobLauncher();

jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());

jobLauncher.run(job, jobParameters);

return "batch success!";

}

}

 

0

정수원님의 프로필 이미지
정수원
지식공유자

혹시 작성하신 코드 공유 가능할까요?

아리마님의 프로필 이미지
아리마

작성한 질문수

질문하기