[SpringBatch 실습] 5. Batch Job 수행시 Step 실패하는 경우2 (Step 실패와 StepExceution 관계)

반응형
728x90
반응형

들어가기전

Batch Job 수행시 Step 실패하는 과정 첫번째 포스팅을 참고하자.

https://devfunny.tistory.com/758

 

[SringBatch 실습] 3. Batch Job 수행시 Step 실패하는 경우

Job 생성 JobExecutionConfiguration.java import lombok.RequiredArgsConstructor; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch..

devfunny.tistory.com

 

 

 

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

 

 

 

 

반응형

Designed by JB FACTORY