2014-10-02 80 views
3

行,Spring批处理作业实例已存在

我知道这已被问过,但我仍然无法找到我的问题的确切答案。我的问题是这样的:我使用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 

我当然可以是一个日期 - 时间参数添加到作业是这样的:

.addLong("time", System.getCurrentTimeMillis()) 

,然后运行作业不止一次。不过,我也想查询作业的最后执行,让我有这样的代码:

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()); 
} 

,这没有返回,因为我没有提供时间参数。所以好像我可以运行一次这个工作并获得最后的执行时间,或者我可以多次运行它,而不是最后的执行时间。我真的坚持:(

回答

3

使用作业浏览器由Luca巴索·里奇的建议。

因为你不知道工作参数,你需要通过实例来查找。

  1. 寻找名为searchExportJob
  2. 工作的最后一个实例
  3. 查找实例的最后一次执行上述

使用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()); 
} 

注意这这种方式代码只适用于2.1.x的Spring Batch 2.2.x及更高版本,API有所不同

1

假设

Spring Batch的使用一些表来存储与其参数来执行各任务。 如果您运行两次使用相同的参数工作,第二个失败,因为作业由作业名和参数标识。

1#解决方案

运行新的工作时,你可以使用JobExecution。

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

2#解决方案

你可以实现自定义JobExecutionDao和执行自定义查询来查找您JobExecutionBATCH_JOB_EXECUTION表。 See here Spring的参考。

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

+0

我可以'因为那时候执行是失败的。如果我没有想到更好的方法,我可能会最终使用您的解决方案2-创建一个自定义的DAO。 – 2014-10-06 14:05:54

+0

@PetarTahchiev让我知道如果工作正常。为了解决这个问题:) – Xstian 2014-10-06 19:11:03

1

还有另外一个界面,您可以使用:JobExplorer
从它的javadoc:

入口点浏览运行或历史的工作和 步骤的执行。由于数据可能会从持久性存储重新水合,它 可能不含有挥发性字段会一直存在,当 执行活跃

+0

我没有看到JobExplorer中的方法,这将帮助我实现我想要的:( – 2014-10-06 14:07:34

相关问题