在事务中启动 Spring 批处理作业

问题描述 投票:0回答:5

我有简单的 Spring 服务(除其他任务外)使用以下代码启动 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);
}

只要调用服务方法时没有事务处于活动状态,这就可以正常工作。但是,通过活跃交易,我得到了这个异常:

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

我无法轻易删除现有事务,因为它是由于某些不在我能力范围内的框架代码而隐含的。

那么,在这种情况下我该如何开始工作呢?新作业不应该使用现有事务。它可以启动自己的事务 - 但如何配置它才能使其工作?

java spring transactions spring-batch
5个回答
6
投票

我也有类似的问题。特别是,我是从一个带有

@Transactional(propagation = Propagation.REQUIRES_NEW)
注释的类中开始我的工作的。为了解决这个问题,我从一个没有活跃交易的地方开始了我的工作。然后我遇到了如上所述的问题 - 以下是我解决它的方法:

在 JobRepository 上将

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

这让我的工作进展顺利。然而,我不确定我现在是否正在处理 2 个未完成的交易,并且想确定我不是。因此,我还删除了类级别的事务注释,并将其移至所有公共方法,除了由我的 Itemprocessor 调用的方法。这样我就解决了这个问题。


5
投票

我的解决方案是启动作业的方法需要用

@Transactional(propagation = Propagation.NOT_SUPPORTED)
进行注释,这将暂停当前事务并在执行后恢复。

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

transactionAttribute

我不需要

setValidateTransactionState(false)
JobRepositoryFactoryBean
    


4
投票


2
投票

JobRepository

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

要使用另一个事务,您可以使用标记为 @Transactional() 的方法

AbstractJobRepositoryFactoryBean.ValidateTransactionState

注入自定义

SimpleJobLauncher.executor
(或创建自定义
Executor.run
并对方法
JobLauncher
执行相同的操作)。



我没有尝试过,因为我没有遇到过这个问题,但希望能有所帮助。


0
投票

这个配置给了我一个错误:

run

jakarta.persistence.TransactionRequiredException:没有事务正在进行中

这个配置给了我一个错误:

@Transactional(propagation = Propagation.NOT_SUPPORTED)

java.lang.IllegalStateException:在 JobRepository 中检测到现有事务。请修复此问题并重试(例如删除@Transactional 注释

对我有用的是:

@Transactional(propagation = Propagation.REQUIRES_NEW)

	
© www.soinside.com 2019 - 2024. All rights reserved.