Spring批处理作业实例已存在

Pet*_*iev 7 spring spring-batch

好,

我知道以前曾经问过,但我仍然无法找到我的问题的明确答案.我的问题是:我使用spring批处理将数据导出到SOLR搜索服务器.它需要每分钟运行一次,因此我可以导出所有更新.第一次执行通过OK,但第二次执行抱怨:

2014-10-02 20:37:00,022 [defaultTaskScheduler-1] ERROR: catching
org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException: A job     instance already exists and is complete for parameters={catalogVersionPK=3378876823725152,
type=UPDATE}.  If you want to run this job again, change the parameters.
    at org.springframework.batch.core.repository.support.SimpleJobRepository.createJobExecution(SimpleJobRepository.java:126)
    at 
Run Code Online (Sandbox Code Playgroud)

当然,我可以像这样在作业中添加日期时间参数:

.addLong("time", System.getCurrentTimeMillis())
Run Code Online (Sandbox Code Playgroud)

然后这个工作可以多次运行.但是,我也想查询作业的最后一次执行,所以我有这样的代码:

DateTime endTime = new DateTime(0);
JobExecution je = jobRepository.getLastJobExecution("searchExportJob", new JobParametersBuilder().addLong("catalogVersionPK", catalogVersionPK).addString("type", type).toJobParameters());
if (je != null && je.getEndTime() != null) {
   endTime = new DateTime(je.getEndTime());
}
Run Code Online (Sandbox Code Playgroud)

这没有任何回报,因为我没有提供时间参数.所以看起来我可以运行一次并获得最后一次执行时间,或者我可以多次运行它而不是上次执行时间.我真的被卡住了:(

Xst*_*ian 6

假设

Spring Batch 使用一些表来存储执行的每个作业及其参数。如果使用相同的参数运行该作业两次,则第二次会失败,因为该作业是由 jobName 和参数标识的。

1#溶液

运行新作业时可以使用 JobExecution。

JobExecution execution = jobLauncher.run(job, new JobParameters());
.....
// Use a JobExecutionDao to retrieve the JobExecution by ID
JobExecution ex = jobExecutionDao.getJobExecution(execution.getId());
Run Code Online (Sandbox Code Playgroud)

2#溶液

您可以实现自定义 JobExecutionDao 并执行自定义查询来查找您的JobExecutionBATCH_JOB_EXECUTION请参阅此处Spring 的参考。

希望我的回答对您有帮助。


Hai*_*man 5

按照 Luca Basso Ricci 的建议使用 Job Explorer。

因为您不知道需要按实例查找的作业参数。

  1. 查找名为 searchExportJob 的作业的最后一个实例
  2. 查找上面实例的最后一次执行

这样你只使用 Spring Batch API

//We can set count 1 because job instance are ordered by instance id descending
//so we know the first one returned is the last instance 
List<JobInstance> instances = jobExplorer.getJobInstances("searchExportJob",0,1);
JobInstance lastInstance = instances.get(0);
List<JobExecution> jobExecutions = jobExplorer.getJobExecutions(lastInstance);

//JobExcectuin is ordered by execution id descending so first 
//result is the last execution
JobExecution  je = jobExecutions.get(0);
if (je != null && je.getEndTime() != null) {
     endTime = new DateTime(je.getEndTime());
 }
Run Code Online (Sandbox Code Playgroud)

请注意,此代码仅适用于 2.1.x 中的 Spring Batch 2.2.x 及更高版本 API 有所不同