使用JobRepositoryFactoryBean进行spring批处理

时间:2014-07-15 09:33:06

标签: spring transactions spring-batch

我遇到的情况是我必须调用批处理并更新服务层中作业的状态。这里JobRepositoryFactoryBean已经包含了事务管理器,因此我不应该使用@Transactional注释我的服务方法。如果我注释,我将在运行时获得异常,说“Existing transaction detected in job repository please fix and try again by removing @Transactional”如果没有注释{ {1}}我收到运行时异常,说“@Transactional”。请帮我解决这个问题。

1 个答案:

答案 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的项目负责人)。