gpt4 book ai didi

spring-batch - Spring Batch 错误(A Job Instance Already Exists)和 RunIdIncrementer 只生成一次

转载 作者:行者123 更新时间:2023-12-02 01:52:11 26 4
gpt4 key购买 nike

我正在使用 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 所以(作业实例)已经存在)

工作背景
<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>

测试.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");

}

}

日志(在第一次运行和第二次运行中检查作业 incetance 参数):
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]

最佳答案

要与工作 Incremater 共进午餐,您需要做两件事

  • 将 RunIdIncremater 附加到您的作业。
  • 使用了解 Incremater 用法的启动器。

  • 我认为您不需要自己的实现,只需使用现有的实现即可。
    将 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:用户作业运算符(operator)
    <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 并且会忽略您使用的那个
    另请参阅以下答案 SpringBatch: Test a JobExecutionListener

    关于spring-batch - Spring Batch 错误(A Job Instance Already Exists)和 RunIdIncrementer 只生成一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22148117/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com