2

我有一个弹簧批处理(2.2.2)应用程序,由于某种原因无法使作业参数增量器工作。该步骤声明如下:

<job id="job1" xmlns="http://www.springframework.org/schema/batch" incrementer="incrementer">
    <step id="step1" parent="step" />
</job>

<bean id="incrementer" class="org.springframework.batch.core.launch.support.RunIdIncrementer" />

当我将断点放入增量器时,它甚至没有被调用。

使用相同的参数调用作业两次会产生以下异常:

A job instance already exists and is complete for parameters={fail=false}.  If you want to run this job again, change the parameters.

我在这里查看了官方样品

https://github.com/spring-projects/spring-batch-admin/tree/master/spring-batch-admin-sample

它有同样的问题

4

3 回答 3

6

老问题,但仍适用于当前版本(3.0.5):

如果您通过以下方式开始作业执行

JobExecution jobExecution = launcher.run(job, jobParameters);

使用例如SimpleJobLauncher类,那么增量器永远不会被调用。如果检查方法的“调用者”,Incrementer.getNext(JobParameters)调用者的数量是有限的:

  • org.springframework.batch.core.launch.support.CommandLineJobRunner

CommandLineJobRunner在调用启动器之前getNext()有条件地调用“-next” :

    if (opts.contains("-next")) {
        JobParameters nextParameters = getNextJobParameters(job);
        Map<String, JobParameter> map = new HashMap<String, JobParameter>(nextParameters.getParameters());
        map.putAll(jobParameters.getParameters());
        jobParameters = new JobParameters(map);
    }

    JobExecution jobExecution = launcher.run(job, jobParameters);
  • org.springframework.batch.core.launch.support.SimpleJobOperator

这由 Spring Admin Web 应用程序使用,它与 CommandLineJobRunner 中的实现基本相同:

if (lastInstances.isEmpty()) {
    parameters = incrementer.getNext(new JobParameters());
    if (parameters == null) {
        throw new JobParametersNotFoundException("No bootstrap parameters found for job=" + jobName);
    }
}
else {
    List<JobExecution> lastExecutions = jobExplorer.getJobExecutions(lastInstances.get(0));
    parameters = incrementer.getNext(lastExecutions.get(0).getJobParameters());
}

logger.info(String.format("Attempting to launch job with name=%s and parameters=%s", jobName, parameters));
try {
    return jobLauncher.run(job, parameters).getId();
}
catch (JobExecutionAlreadyRunningException e) {
    throw new UnexpectedJobExecutionException(String.format(ILLEGAL_STATE_MSG, "job already running", jobName,
            parameters), e);
}

因此,如果您使用 JobLauncher 类来启动 Jobs,在调用 jobLauncher 之前必须注意调用增量器,以使用所需的值增强作业参数。

于 2015-11-24T11:34:01.020 回答
1

我看到没有人给你一个正确的答案,所以这就是它(即使晚了一年也许它会帮助其他人):

可以直接调用CommandLineJobRunner类的main函数。例如:

String[] args = new String[]{"spring/batch/jobs/helloWorldJob.xml", "helloWorldJob", "name(string)=Spring", "-next"};
CommandLineJobRunner.main(args);

基本上,当您从命令行(或任何其他 Java 应用程序)运行 Spring Batch 时,这就是您正在做的事情。

于 2015-01-23T08:48:45.273 回答
0

如果您CommandLineJobRunner使用-next选项 else 运行,最好的解决方案是使用时间戳作业参数来使每个作业实例与其他作业实例不同。

于 2013-11-06T16:26:05.013 回答