복붙노트

[SPRING] Spring Batch : Spring MVC 컨트롤러 내에서 새로운 스레드로 작업 시작하기

SPRING

Spring Batch : Spring MVC 컨트롤러 내에서 새로운 스레드로 작업 시작하기

Spring MVC 컨트롤러에서 시작하는 Spring-Batch 작업이 있습니다. 컨트롤러는 사용자로부터 업로드 된 파일을 가져오고 작업은 파일을 처리하기로되어 있습니다.

@RequestMapping(value = "/upload")
public ModelAndView uploadInventory(UploadFile uploadFile, BindingResult bindingResult) {

    // code for saving the uploaded file to disk goes here...

    // now I want to launch the job of reading the file line by line and saving it to the database,
    // but I want to launch this job in a new thread, not in the HTTP request thread,
    // since I so not want the user to wait until the job ends.
    jobLauncher.run(
                    jobRegistry.getJob(JOB_NAME),
                    new JobParametersBuilder().addString("targetDirectory", folderPath).addString("targetFile", fileName).toJobParameters()
                    );

    return mav;
}

나는 다음 XML 설정을 시도했다 :

<job id="writeProductsJob" xmlns="http://www.springframework.org/schema/batch">
    <step id="readWrite">
        <tasklet task-executor="taskExecutor">
            <chunk reader="productItemReader" writer="productItemWriter" commit-interval="10" />
        </tasklet>
    </step>
</job>

<bean id="taskExecutor"
    class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="5" />
    <property name="maxPoolSize" value="5" />
</bean>

...하지만 멀티 스레딩은 작업 경계 내에서만 발생합니다. 즉, 컨트롤러 스레드는 작업이 끝날 때까지 기다리고 작업 실행은 여러 스레드에서 처리됩니다 (좋은 일이지만 원하는 것은 아닙니다). 필자가 원했던 점은 작업 스레드가 종료 될 때까지 기다리지 않고 컨트롤러 스레드가 계속 실행되는 동안 별도의 스레드 (또는 스레드)에서 작업이 시작된다는 것입니다.

스프링 배치를 사용하여이를 달성 할 수있는 방법이 있습니까?

해결법

  1. ==============================

    1.공식 문서는 4.5.2의 정확한 문제와 해결책을 설명합니다. 웹 컨테이너 내에서 작업 실행 :

    공식 문서는 4.5.2의 정확한 문제와 해결책을 설명합니다. 웹 컨테이너 내에서 작업 실행 :

    스프링 배치 http://static.springsource.org/spring-batch/reference/html-single/images/launch-from-request.png

    따라서 TaskExecutor를 사용하려고 할 때 꽤 가까웠지만 대신 JobLauncher에 전달해야합니다.

    <bean id="jobLauncher"
          class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository" />
        <property name="taskExecutor" ref="taskExecutor"/>
    </bean>
    

    면책 조항 : 저는 Spring Batch를 사용한 적이 없습니다 ...

  2. ==============================

    2.jobLauncher.run () 메서드는 다음과 같이 새 스레드에서 호출 할 수 있습니다.

    jobLauncher.run () 메서드는 다음과 같이 새 스레드에서 호출 할 수 있습니다.

    @RequestMapping(value = "/upload")
    public ModelAndView uploadInventory(UploadFile uploadFile, BindingResult bindingResult) {
      [...]
    
      final SomeObject jobLauncher = [...]
      Thread thread = new Thread(){
        @Override
        public void run(){
          jobLauncher.run([...]);
        }
      };
      thread.start();
    
      return mav;
    }
    

    thread.start () 행은 새 스레드를 생성 한 다음 그 아래의 코드를 계속 실행합니다.

    jobLauncher가 로컬 변수 인 경우 익명 Thread 클래스 내부에서 사용하려면 final로 선언해야합니다.

  3. ==============================

    3.처리 오류를 클라이언트에 표시 할 필요가 없으면 별도의 스레드에서 스프링 배치 작업을 시작할 수 있습니다.

    처리 오류를 클라이언트에 표시 할 필요가 없으면 별도의 스레드에서 스프링 배치 작업을 시작할 수 있습니다.

  4. from https://stackoverflow.com/questions/9114162/spring-batch-starting-a-job-from-within-a-spring-mvc-contorller-with-a-new-thre by cc-by-sa and MIT license