已经在事务中启动弹出批处理作业

时间:2013-08-08 11:55:50

标签: java spring transactions spring-batch

我有简单的Spring-Service,其中包括(以及其他任务)使用以下代码启动spring批处理作业:

@Autowired
private JobRegistry jobRegistry;

@Autowired
private JobLauncher jobLauncher;

public void startMyJob() {
    Job job = jobRegistry.getJob("myJobName");
    JobParameters jobParameters = new JobParametersBuilder().toJobParameters();
    jobLauncher.run(job, jobParameters);
}

只要在调用Serivce-Method时没有事务处于活动状态,这样就可以正常工作。但是,对于活动事务,我会遇到此异常:

Caused by: java.lang.IllegalStateException: Existing transaction detected in JobRepository. Please fix this and try again (e.g. remove @Transactional annotations from client).

我无法轻松删除现有的交易,因为由于某些框架代码不在我的范围内,因此暗示了这一点。

那么,我怎样才能在这种背景下开始这项工作呢?新工作不应该使用现有的交易。它可能只是启动自己的事务 - 但如何配置它以使其工作?

4 个答案:

答案 0 :(得分:4)

我有类似的问题。特别是,我从一个用@Transactional(propagation = Propagation.REQUIRES_NEW)注释的类中开始工作。为了解决这个问题,我从某个地方开始工作,那里没有活动交易。然后我如上所述遇到了你的问题 - 这就是我解决它的方法:

在JobRepository上将validateTransactionState设置为false - 它现在忽略了在调用的类ItemProcessor中自动创建的事务(因为所述类使用@Transcational注释,如上所述)。

这使我的工作运行得很好。但是,我不确定我现在是在处理2次公开交易,并且想确定我不是。所以我还删除了类级别的transcational注释,并将其移动到所有公共方法,除了我的Itemprocessor调用的方法。因此我解决了这个问题。

答案 1 :(得分:2)

使用AbstractJobRepositoryFactoryBean.ValidateTransactionState,但要小心使用(警告:前方龙)。

要使用其他交易,您可以使用标记为@Transactional()的方法SimpleJobLauncher.executor注入自定义Executor.run(或创建自定义JobLauncher并对方法{{1执行相同操作}})。

我没有尝试,因为我没有遇到问题,但希望可以帮助。

答案 2 :(得分:2)

我的解决方案是启动作业的方法需要使用@Transactional(propagation = Propagation.NOT_SUPPORTED)进行注释,这将暂停当前事务并在执行后恢复。

如果您需要与默认设置不同的内容,可以在读者和作者身上设置transactionAttribute

setValidateTransactionState(false)JobRepositoryFactoryBean

我不需要JobRepository

答案 3 :(得分:0)

我通过创建一个单独的bean AsyncJobLauncher来解决这个问题,它有一个与JobLauncher具有相同签名的run方法,并委托给真实的那个,但标有Spring的@Async。因此,工作的启动发生在新线程的后台,因此它在自己的事务中。