Spring Package: starting a job from Spring MVC contorller WITH NEW NEW

I have a Spring -Batch job that I run from Spring MVC. The controller receives the downloaded file from the user, and the task must process the file:

@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; } 

I tried the following XML configuration:

 <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> 

... but it seems that multithreading only occurs within the boundaries of the work itself. Ie, the controller thread is waiting for the job to finish, and the job is being processed by several threads (which is good, but not the main thing I wanted). The main thing I wanted was that the task will be launched in a separate thread (or threads), while the controller thread will continue to execute it, without waiting for the completion of the task threads.

Is there a way to achieve this using Spring-batch?

+4
source share
3 answers

The official documentation describes your exact problem and solution in 4.5.2. Running tasks from the web container :

[...] The controller starts the job using the JobLauncher , which was configured to run asynchronously , which immediately returns a JobExecution . The work will most likely be started, however this non-blocking behavior allows the controller to return immediately , which is required when processing the HttpRequest.

Spring Package http://static.springsource.org/spring-batch/reference/html-single/images/launch-from-request.png

So, you tried very closely to use TaskExecutor , however you need to pass it instead of JobLauncher :

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

Disclaimer: I have never used Spring Package ...

+6
source

The jobLauncher.run() method can be called in the new Thread like this:

 @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; } 

The string thread.start() will create a new thread and then continue executing the code below.

Note that if jobLauncher is a local variable, it must be declared final so that it is used inside the anonymous Thread class.

+3
source

If you do not need to display processing errors for your client, you can run the spring batch job in a separate thread.

+1
source

Source: https://habr.com/ru/post/1394401/


All Articles