들어가기전
Batch Job 수행시 Step 실패하는 과정 첫번째 포스팅을 참고하자.
https://devfunny.tistory.com/758
Job 생성
StepExecutionConfiguration.java
import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/*
--job.name=stepExecutionTestJob
*/
@Configuration
@RequiredArgsConstructor
public class StepExecutionConfiguration {
// job 생성
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
@Bean
public Job stepExecutionTestJob() {
return this.jobBuilderFactory.get("stepExecutionTestJob")
.start(executionTestStep1())
.next(executionTestStep2())
.next(executionTestStep3())
.build();
}
@Bean
public Step executionTestStep1() {
return stepBuilderFactory.get("executionTestStep1")
.tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
System.out.println("executionTestStep1");
return RepeatStatus.FINISHED;
}
})
.build();
}
@Bean
public Step executionTestStep2() {
return stepBuilderFactory.get("executionTestStep2")
.tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
System.out.println("executionTestStep1");
throw new RuntimeException("step2 failed");
// return RepeatStatus.FINISHED;
}
})
.build();
}
@Bean
public Step executionTestStep3() {
return stepBuilderFactory.get("executionTestStep3")
// 빈으로 등록해도되고, 이렇게 객체 생성해도 된다.
.tasklet(new CustomTasklet())
.build();
}
}
CustomTasklet.java
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
public class CustomTasklet implements Tasklet {
/**
* 비즈니스 로직 구현
* @param stepContribution
* @param chunkContext
* @return
* @throws Exception
*/
@Override
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
System.out.println("executionTestStep3");
return RepeatStatus.FINISHED;
}
}
application.yml
spring:
config:
activate:
on-profile: postgresql
datasource:
url: jdbc:postgresql://localhost:5432/...
username: ...
password: ...
driver-class-name: org.postgresql.Driver
batch:
job:
names: ${job.name:NONE} # --job.name=batchJob1 로 실행시키겠다는 의미. 아무런 파라미터로 넘기지 않으면 NONE이라는 이름으로 실행되어 아무런 배치잡이 수행되지 않는다.
Batch 수행
Job 흐름
executionTestStep1 | 성공 |
executionTestStep2 | 실패 |
executionTestStep3 | 실패 |
DB 테이블 조회
1) BATCH_JOB_EXECUTION
COLUMN | VALUE |
STATUS | FAILED |
EXIT_CODE | FAILED |
JOB_EXECUTION_ID | 23 |
2) BATCH_JOB_INSTANCE
COLUMN | VALUE |
JOB_NAME | JobExecutionTestJob |
3) BATCH_STEP_EXECUTION
3개의 STEP의 JOB_EXECUTION_ID 는 모두 동일하다.
- executionTestStep1
COLUMN | VALUE |
STEP_NAME | JobExecutionTestStep1 |
EXIT_CODE | COMPLETED |
STATUS | COMPLETED |
JOB_EXECUTION_ID | 23 |
- executionTestStep2
Step 시작 시점에 생성되므로 현재의 스텝이 실패했어도 생성은 되었다. 대신, 상태값이 FAILED다.
COLUMN | VALUE |
STEP_NAME | JobExecutionTestStep2 |
EXIT_CODE | FAILED |
STATUS | FAILED |
JOB_EXECUTION_ID | 23 |
오류 메시지 확인이 가능하다.
COLUMN | VALUE |
EXIT_CODE | FAILED |
EXIT_MESSAGE | java.lang.RuntimeException: step2 failed ... |
- executionTestStep3
executionTestStep2에서 에러가 발생했기 때문에, executionTestStep3에 대한 BATCH_STEP_EXECTUION 데이터가 생성되지 않는다.
해당 Job을 다시 수행한다면?
고의로 오류를 발생시켰던 코드를 정상적으로 종료되도록 수정하자.
@Bean
public Step executionTestStep2() {
return stepBuilderFactory.get("executionTestStep2")
.tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
System.out.println("executionTestStep2");
return RepeatStatus.FINISHED;
}
})
.build();
}
결과
executionTestStep2
executionTestStep3
executionTestStep1은 수행하지 않고, executionTestStep2, executionTestStep3 가 실행되었다.
DB 테이블 조회
1) BATCH_JOB_EXECUTION
처음에 실행했을때의 JOB_EXECUTION_ID 23 뒤에 새로운 데이터가 생성되었다.
COLUMN | VALUE |
STATUS | COMPLETED |
EXIT_CODE | COMPLETED |
JOB_EXECUTION_ID | 24 |
2) BATCH_JOB_INSTANCE
신규로 생성되지 않는다.
COLUMN | VALUE |
JOB_NAME | JobExecutionTestJob |
3) BATCH_STEP_EXECUTION
executionTestStep1은 이전에 성공했던 STEP 이므로, 수행되지 않았다. 따라서 신규로 생성된 데이터는 없다. 만약 성공했던 executionTestStep1도 수행하려면 별도로 옵션값을 설정해줘야한다. (추후 배울 예정이다.)
- executionTestStep1
COLUMN | VALUE |
STEP_NAME | JobExecutionTestStep1 |
EXIT_CODE | COMPLETED |
STATUS | COMPLETED |
JOB_EXECUTION_ID | 23 |
- executionTestStep2
성공적으로 수행되었다.
COLUMN | VALUE |
STEP_NAME | JobExecutionTestStep2 |
EXIT_CODE | COMPLETED |
STATUS | COMPLETED |
JOB_EXECUTION_ID | 24 |
- executionTestStep3
COLUMN | VALUE |
STEP_NAME | JobExecutionTestStep3 |
EXIT_CODE | COMPLETED |
STATUS | COMPLETED |
JOB_EXECUTION_ID | 24 |
'Coding > Spring Batch' 카테고리의 다른 글
[SpringBatch 실습] 7. BATCH 테이블 Prefix 변경해보기 (0) | 2022.05.26 |
---|---|
[SpringBatch 실습] 6. ExecutionContext (StepExecution, JobExecution 관계) 예제로 흐름 파악하기 (0) | 2022.05.24 |
[SpringBatch 실습] 4. Tasklet 클래스를 생성하여 Job에 설정하기 (0) | 2022.05.22 |
[SpringBatch 실습] 3. Batch Job 수행시 Step 실패하는 경우 (0) | 2022.05.22 |
[SpringBatch 실습] 2. ApplicationRunner 구현 클래스로 Job 수행시키기 (0) | 2022.05.21 |