본문 바로가기

SPRING

[SPRING] Spring batch 오류 해결 Step already complete or not restartable, so no action to execute: StepExecution:

 

이전에 만들었던 spring batch 코드를 다시 실행시켜보니 다음과 같은 오류가 발생했다.

 Step already complete or not restartable, so no action to execute: StepExecution:

 

 

 

내 코드는 이전 포스팅에서 예제로 사용했던 miracleMorning() job이다. 

Spring boot batch 및 scheduler 예제 포스팅 👉  https://seo-0.tistory.com/28

 

왜그런지 한참 찾아보니 job builder를 선언해주는 부분에서 .end()로 flow를 종료하면서 Job의 BatchStatus와 ExitStatus가 COMPLETED으로 리턴된다. 이 때 Job의 재시작이 불가능하다!!!

 

    public Job miracleMorning() {
        return jobBuilderFactory.get("miracleMorning")
                .start(wakeUp())
                .on("COMPLETED")
                .to(drinkCoffee())
                .on("*")
                .to(exercise())
                .on("*")
                .end()					=> 요기!!!!!!!!

                .from(wakeUp())
                .on("*")
                .to(drinkWater())
                .on("*")
                .to(exercise())
                .on("*")
                .end()					=> 요기!!!!!!!!
                .end().build();
    }

 

 

그래서 내가 택한 방법은 .allowStartIfComplete() 속성을 통해 COMPLETED로 끝난 Step도 재실행 대상에 포함시켜주도록 하였다.

다음 코드처럼 모든 step에 .allowStartIfComplete(true)를 추가해주고 재실행하니 job은 COMPLETED이지만 다시 실행이 가능해졌다!

 

    @Bean
    public Step wakeUp() {
        return stepBuilderFactory.get("wakeUp")
                .tasklet((contribution, chunkContext) -> {
                    log.info("----- wakeUp");

                    String result = "COMPLETED";

                    //Flow에서 on은 RepeatStatus가 아닌 ExitStatus를 바라본다.
                    if (result.equals("COMPLETED"))
                        contribution.setExitStatus(ExitStatus.COMPLETED);
                    else if (result.equals("FAIL"))
                        contribution.setExitStatus(ExitStatus.FAILED);
                    else if (result.equals("UNKNOWN"))
                        contribution.setExitStatus(ExitStatus.UNKNOWN);

                    return RepeatStatus.FINISHED;
                })
                .allowStartIfComplete(true) // COMPLETED로 끝난 STEP도 재실행 대상에 포함시켜줌 (원래 job이 한번 completed되면 재실행이 안됨)
                .build();
    }

 

 

 

추가로 다음은 그냥 알아두면 좋은 스프링 설정들!! (application.yml)

 

여러개의 Job을 BatchJobConfig.java 파일에 선언해놓고 스케쥴러에서 BatchJobConfig파일에 있는 여러 job들 중 하나의 job만 실행하고 싶다. 하지만 아무 설정도 안해놓으면 어플리케이션이 실행됐을 때 BatchJobConfig 파일에 있는 모든 job들이 한번씩 실행되고 스케쥴러가 실행되는 것이었다.

나는 스케쥴러만 돌아가게 하고 싶은데...!

이때 yml 파일에 다음과 같은 설정을 해놓으면 자동으로 job들이 전부 실행되는 것을 막을 수 있다

spring.batch.job.enabled: false

 

 

여러개의 Job을 BatchJobConfig.java 파일에 선언해놓고 어플리케이션을 실행하면 모든 job들이 한번씩 모두 실행된다.

나는 특정 job 하나만 실행하고 싶은데...!

이때는 yml 파일에 다음과 같이 내가 실행하고자 하는 job의 name을 설정해놓으면 해당 name을 가진 job만 실행된다.

spring.batch.job.names: miracleMorning