我遇到的情况是我必须调用批处理并更新服务层中作业的状态。这里JobRepositoryFactoryBean
已经包含了事务管理器,因此我不应该使用@Transactional
注释我的服务方法。如果我注释,我将在运行时获得异常,说“Existing transaction detected in job repository please fix and try again by removing @Transactional
”如果没有注释{ {1}}我收到运行时异常,说“@Transactional
”。请帮我解决这个问题。
答案 0 :(得分:0)
服务不应直接与JobRepositoryFactoryBean或Job Repository本身交互。不建议在Spring Batch基础结构之外使用JobRepository API。
使用数据库表可以跟踪批处理作业的执行情况,并查看作业和步骤级别的情况,以获取更多信息,请参阅here。如果您认为需要有关于该作业的其他数据,请添加您自己的表格。
要更新作业本身的状态,请使用 jobExecution.setExitStatus或jobExecution.setStatus API。 阅读有关差异bewteeb ExitStatus和BatchStatus here。
我建议在你的情况下使用一个求职者。 Job Listener与tasklet不同,或者step侦听器在块的事务之外执行。请参阅以下博文here
@Component
public class JobMonitorListener {
private static Log LOGGER = LogFactory.getLog(JobMonitorListener.class);
@Autowired
JobMonitorService monitorService;
@BeforeJob
public void beforeJob(JobExecution jobExecution){
LOGGER.info("Before Job");
monitorService.persistAddtionalData(date);
}
@AfterJob
public void afterJob(JobExecution jobExecution){
LOGGER.info("Afetr Job");
monitorService.persistAddtionalData(date);
jobExecution.setExitStatus(new ExitStatus("Failed by Monitor"));
jobExecution.setStatus(BatchStatus.FAILED);
}
}
服务:
@Component
public class JobMonitorServiceImpl implements JobMonitorService {
@Transactional("transactionManager")
public void persistAddtionalData(Object) {
}
}
你的工作xml
<batch:job id="job">
<batch:listeners >
<batch:listener ref="jobMonitorListener"/>
</batch:listeners>
...
</batch:job>
确保使用的事务管理器与JobRepostory使用的事务管理器不同。有关更多Transaction Issue with Spring Batch JobRepository in Unit Test
,请参阅我的回答无论如何使用带有Spring批处理的@Transactional是很棘手的(参见Michael Minella的评论Spring Batch. Call methods with rollbackFor,Spring Batch的项目负责人)。