在我的Spring Batch应用程序中,我使用PostgreSQL作为作业存储库,并使用以下登录名来重新启动未完成的作业:
try {
jobRegistry.register(new ReferenceJobFactory(documetPipelineJob));
List<String> jobs = jobExplorer.getJobNames();
for (String job : jobs) {
Set<JobExecution> jobExecutions = jobExplorer.findRunningJobExecutions(job);
for (JobExecution jobExecution : jobExecutions) {
jobExecution.setStatus(BatchStatus.STOPPED);
jobExecution.setEndTime(new Date());
jobRepository.update(jobExecution);
Long jobExecutionId = jobExecution.getId();
jobOperator.restart(jobExecutionId);
}
}
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
但是此逻辑失败,但有以下异常:
2018-08-01 14:33:21.777错误32306 --- [main] c.v.p.d.service.batch.BatchServiceImpl:非法状态(仅发生 在竞争条件下):作业执行已与 名称= documetPipelineJob和参数=
这里可能有什么问题以及如何解决?
已更新
看起来jobRepository.update(jobExecution);
不会将更改提交到数据库。如何正确地将更改提交到数据库?顺便说一句-这种逻辑在H2内存数据库中正常工作。
答案 0 :(得分:0)
为了解决此问题,我添加了incrementer(new RunIdIncrementer())
:
jobBuilderFactory.get("documetPipelineJob")
.incrementer(new RunIdIncrementer())
.start(initStep)
我还扩展了重启逻辑以停止运行步骤:
try {
jobRegistry.register(new ReferenceJobFactory(documetPipelineJob));
List<String> jobs = jobExplorer.getJobNames();
for (String job : jobs) {
Set<JobExecution> jobExecutions = jobExplorer.findRunningJobExecutions(job);
for (JobExecution jobExecution : jobExecutions) {
Collection<StepExecution> stepExecutions = jobExecution.getStepExecutions();
for (StepExecution stepExecution : stepExecutions) {
BatchStatus status = stepExecution.getStatus();
if (status.isRunning() || status == BatchStatus.STOPPING) {
stepExecution.setStatus(BatchStatus.STOPPED);
stepExecution.setEndTime(new Date());
jobRepository.update(stepExecution);
}
}
jobExecution.setStatus(BatchStatus.STOPPED);
jobExecution.setEndTime(new Date());
jobRepository.update(jobExecution);
Long jobExecutionId = jobExecution.getId();
jobOperator.restart(jobExecutionId);
}
}
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
然后,我遇到了以下文章中描述的问题:Serialize Transaction Issue我同时运行多个批处理作业。
我通过用JobRepository
配置ISOLATION_READ_UNCOMMITTED
来解决它:
@Override
protected JobRepository createJobRepository() throws Exception {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(dataSource);
factory.setTransactionManager(transactionManager);
factory.setIsolationLevelForCreate("ISOLATION_READ_UNCOMMITTED");
factory.afterPropertiesSet();
return factory.getObject();
}