使用不同的参数同时执行多个弹簧批处理作业

时间:2016-03-24 07:29:01

标签: java spring tomcat spring-batch

我配置了一个弹簧批处理作业,它在spring webservice中运行。这项工作有几个步骤。我已经在不同的tomcats中部署了这个web服务的两个实例(但是这两个实例都使用相同的mysql数据库)。

我想在两个tomcats(每个一个)中同时运行一个具有不同参数的弹簧批处理作业。我没有使用分区,每个工作的参数完全不同。

我在一只雄猫中开始工作,一切看起来都很好。但是当我在第二个tomcat中开始第二个作业时,作业被创建但是没有启动,甚至没有执行第一步的第一行od代码。

我不是使用弹簧批的专家,所以也许我做错了。但是如果spring批处理作业在两个单独的tomcat实例中运行,它们应该并行运行吗?

这是作业配置:

   <?xml version="1.0" encoding="UTF-8"?>
    <beans 
        xmlns="http://www.springframework.org/schema/beans" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:batch="http://www.springframework.org/schema/batch"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/batch 
            http://www.springframework.org/schema/batch/spring-batch-3.0.xsd">

        <job id="uploadProjectDataJobNormal " xmlns="http://www.springframework.org/schema/batch">
            <step id="setupProject" next="loadReferenceBuilds">
                <tasklet ref="projectSetupTasklet"/>
                <listeners>
                    <listener ref="promotionListener"/>
                    <listener ref="snpAwareStepListener"/>
                    <listener ref="snpAwareItemReadListener"/>
                </listeners>
            </step>

        <step id="loadReferenceBuilds" next="snpToMorph">
            <tasklet>
                <chunk reader="faiReader" processor="faiProcessor" writer="faiWriter" commit-interval="100"/>
            </tasklet>
            <listeners>
                <listener ref="promotionListener"/>
                <listener ref="snpAwareStepListener"/>
                <listener ref="snpAwareItemReadListener"/>
            </listeners>
        </step>

        <step id="snpToMorph" next="indelToMorph">
            <tasklet>
                <chunk reader="snpReader" processor="snpProcessor" writer="snpWriter" commit-interval="100"/>
            </tasklet>
            <listeners>
                <listener ref="promotionListener"/>
                <listener ref="snpAwareStepListener"/>
                <listener ref="snpAwareItemReadListener"/>
            </listeners>
        </step>

         <step id="indelToMorph">
            <tasklet>
                <chunk reader="indelReader" processor="indelProcessor" writer="indelWriter" commit-interval="100"/>
            </tasklet>
            <listeners>
                <listener ref="promotionListener"/>
                <listener ref="snpAwareStepListener"/>
                <listener ref="snpAwareItemReadListener"/>
            </listeners>
        </step>
<listeners>
            <listener ref="snpAwareBatchJobListener"/>
        </listeners>
</job>

这就是我开始工作的方式:

this.jobLauncher.run(this.uploadProjectDataJobNormal,jobParameters);

作业参数具有某些参数,这些参数在两个作业之间是唯一的,例如日期,我要上传的元素的名称。

以下一种方式配置作业存储库和启动器:

/**
 * Job repository.
 * 
 * @return the job repository.
 * @throws Exception in case the job repository could not be created.
 */
@Bean
public JobRepository jobRepository() throws Exception {
    JobRepositoryFactoryBean jobRepositoryFactory = new JobRepositoryFactoryBean();
    jobRepositoryFactory.setDataSource(this.persistenceConfig.dataSource());
    jobRepositoryFactory.setTransactionManager(this.persistenceConfig.transactionManager());
    jobRepositoryFactory.setIsolationLevelForCreate("ISOLATION_DEFAULT");
    return jobRepositoryFactory.getJobRepository();
}

/**
 * Job launcher.
 * 
 * @return the job launcher.
 * @throws Exception in case the job launcher could not be created.
 */
@Bean
public JobLauncher jobLauncher() throws Exception {
    SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
    jobLauncher.setJobRepository(this.jobRepository());
    jobLauncher.setTaskExecutor(this.taskExecutor());
    return jobLauncher;
}

/**
 * Task executor.
 * 
 * @return the task executor.
 */
@Bean
public TaskExecutor taskExecutor() {
    SimpleAsyncTaskExecutor ex = new SimpleAsyncTaskExecutor();
    ex.setConcurrencyLimit(1);
    return ex;
}

更新:我想到的一个解决方案是使用另一个名称创建第二个作业声明,例如&#34; uploadProjectDataJobNormal2&#34;。这会有帮助吗?

1 个答案:

答案 0 :(得分:2)

最后解决方案比预期简单。在作业启动器中将并发更改为2:

ex.setConcurrencyLimit(2);

我相信,如果Spring批处理作业在不同的JVM中运行,那将不会影响,但确实如此。