Spring Batch错误(作业实例已存在),RunIdIncrementer仅生成一次 [英] Spring Batch error (A Job Instance Already Exists) and RunIdIncrementer generates only once

查看:14
本文介绍了Spring Batch错误(作业实例已存在),RunIdIncrementer仅生成一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Spring Batch&;Quartz读取数据库表并写入另一个表。数据库为Oracle,为C3P0

问题是每个作业都必须有唯一的参数,我尝试了RunIdIncrementer,并且我尝试了此代码:

public class JobRerunner implements JobParametersIncrementer {

    @Override
    public JobParameters getNext(JobParameters parameters) {
        System.out.println("got job parameters: " + parameters);
        if (parameters==null || parameters.isEmpty()) {
            return new JobParametersBuilder().addLong("run.id", System.currentTimeMillis()).toJobParameters();
        }
        long currentTime = parameters.getLong("run.id",System.currentTimeMillis()) + 1;
        return new JobParametersBuilder().addLong("run.id",currentTime).toJobParameters();
    }

}

但是我遇到了同样的问题,run.id只生成了一次,第二次运行作业时完全没有参数,第三次运行时也没有参数(第二次和第三次运行JobParameter=null so(作业实例已经存在)

作业上下文

<batch:job id="readyReqPoolJob" restartable="true">
    <batch:step id="readyReqPoolStep">
        <batch:tasklet>
            <batch:chunk reader="readyReqPoolReader" writer="readyReqPoolWrtiter"
                commit-interval="100" />
        </batch:tasklet>
    </batch:step>
</batch:job>


<!-- ======================================================= -->
<!-- 6) READER -->
<!-- ======================================================= -->
<bean id="readyReqPoolReader"
    class="org.springframework.batch.item.database.JdbcCursorItemReader">
    <property name="dataSource" ref="dataSource" />
    <property name="sql" value="select * from SF_ILA_Ready_Request_Pool" />
    <property name="rowMapper" ref="ReadyReqPoolRowMapper" />
</bean>
<bean id="readyReqPoolWrtiter"
    class="com.housekeepingservice.readyrequestpoolarchive.ReadyReqPoolArchiveWriter" />


<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass"
        value="org.springframework.batch.sample.quartz.JobLauncherDetails" />
    <property name="jobDataAsMap">
        <map>
            <entry key="jobName" value="readyReqPoolJob" />
            <entry key="jobLocator" value-ref="jobRegistry" />
            <entry key="jobLauncher" value-ref="jobLauncher" />
        </map>
    </property>
</bean>

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <bean id="cronTrigger"
            class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
            <property name="jobDetail" ref="jobDetail" />
            <property name="cronExpression" value="0 0/5 * * * ?" />
        </bean>
    </property>
</bean>

主上下文:

<import resource="classpath:spring/batch/config/readyReqPoolContext.xml"
<import resource="classpath:spring/batch/config/jdbc.commons.xml" />
    <!-- 1) USE ANNOTATIONS TO CONFIGURE SPRING BEANS -->
    <context:component-scan base-package="com.housekeepingservice" />


    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager" />
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean
        class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
        <property name="jobRegistry" ref="jobRegistry" />
    </bean>

    <bean id="jobRegistry"
        class="org.springframework.batch.core.configuration.support.MapJobRegistry" />

    <!-- 3) JOB REPOSITORY  -->

    <bean id="jobRepository" 
        class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
        <property name="transactionManager" ref="transactionManager" />
    </bean>

    <!-- 4) LAUNCH JOBS FROM A REPOSITORY -->
    <bean id="jobLauncher"
        class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository" />
        <property name="taskExecutor" ref="taskExecutor" />
    </bean>
    <bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor" />

    <bean id="jobExplorer"
        class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean">
        <property name="dataSource" ref="dataSource" />
    </bean>
        <bean name="jobParamatersIncrementer" class="org.springframework.batch.core.launch.support.RunIdIncrementer">
    </bean>

Test.java

public class Test {
    public static void main(String[] args) {

        String[] springConfig = { "spring/batch/config/mainContext.xml" };

        ApplicationContext context = new ClassPathXmlApplicationContext(
                springConfig);
        JobRerunner rerun = new JobRerunner();

        JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");

        Job readyRequestPoolJob = (Job) context.getBean("readyReqPoolJob");


        try {


            JobParameters jobParameters = new JobParameters();
             JobExecution execution2 = jobLauncher.run(readyRequestPoolJob, rerun.getNext(jobParameters));

            System.out.println("Exit Status : " + execution2.getStatus());


        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("Done");

    }

}

log(检查第一次运行和第二次运行的作业增量参数):

17:00:27,053  INFO SimpleJobLauncher:132 - Job: [FlowJob: [name=readyReqPoolJob]] launched with the following parameters: **[{run.id=1393855226339}]**
17:00:27.085 [Timer-0] DEBUG org.quartz.utils.UpdateChecker - Checking for available updated version of Quartz...
17:00:27,272  INFO SimpleStepHandler:135 - Executing step: [readyReqPoolStep]
17:02:08,791  INFO SimpleJobLauncher:135 - Job: [FlowJob: [name=readyReqPoolJob]] completed with the following parameters: [{run.id=1393855226339}] and the following status: [COMPLETED]
17:10:00.005 [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-1] DEBUG org.quartz.core.JobRunShell - Calling execute on job DEFAULT.jobDetail
17:10:00,008  INFO JobLauncherDetails:69 - Quartz trigger firing with Spring Batch jobName=readyReqPoolJob
17:10:00,036  INFO SimpleJobLauncher:132 - Job: [FlowJob: [name=readyReqPoolJob]] launched with the following parameters: **[{}]**
17:10:00,059  INFO SimpleStepHandler:135 - Executing step: [readyReqPoolStep]

推荐答案

要用JOB Incremater给工作提供午餐,您需要两样东西

  1. 将RunIdIncremater附加到您的作业。
  2. 使用能够识别使用率增量的启动程序。

我认为您自己的实现没有任何需要,只需使用现有实现即可。
将RunIdIncremater附加到您的作业。

<batch:job id="readyReqPoolJob" incrementer="runIdIncrementer" restartable="true">
</batch:job>
<bean id="runIdIncrementer" 
class="org.springframework.batch.core.launch.support.RunIdIncrementer"/>

使用启动器
要启动它,您应该使用以下选项之一:
选项1:带有-next选项的CommandLineJobRunner请参阅API

选项2:用户作业操作员

<bean id="jobOperator"
        class="org.springframework.batch.core.launch.support.SimpleJobOperator">
        <property name="jobRepository" ref="jobRepository" />
        <property name="jobLauncher" ref="jobLauncher" />
        <property name="jobRegistry" ref="jobRegistry" />
        <property name="jobExplorer" ref="jobExplorer" />
</bean>

在代码中

jobOperator.startNextInstance(jobName)

选项3:在Junit中,您可以使用JobLauncherTestUtils。
请注意,它有自己的ID Incremater,将忽略您使用的ID Incremater
另请参阅以下答案SpringBatch: Test a JobExecutionListener

这篇关于Spring Batch错误(作业实例已存在),RunIdIncrementer仅生成一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆