当前位置: 首页 > 知识库问答 >
问题:

Quartz作业未参与Spring托管事务(Quartz Spring批量启动)

殳俊
2023-03-14

我有几个spring批处理作业,如果在spring批处理中触发作业执行,这些作业可以正常工作。这些作业将使用JpaItemWriter对数据库进行读写,其中需要事务。

我的问题是,我有一个quartz调度器,它被配置为定期运行这些作业,我得到了“javax.persistence.TransactionRequiredException:无事务正在进行”错误。我知道目前quartz正在实例化作业bean,而不是spring本身,这使得bean不知道spring管理的正在进行的事务,如果我错了,请纠正我。

然而,我尝试了很多方法,但都不管用。以下是我目前的配置:

石英属性

org.quartz.scheduler.instanceName=sample_instance
org.quartz.scheduler.instanceId=AUTO
org.quartz.threadPool.threadCount=5

org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreCMT
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.MSSQLDelegate
org.quartz.jobStore.useProperties=true
org.quartz.jobStore.misfireThreshold=60000
org.quartz.jobStore.tablePrefix=QRTZ_

org.quartz.jobStore.isClustered=true
org.quartz.jobStore.clusterCheckinInterval=20000

SchedulerConfig。JAVA

@EnableScheduling
@Configuration
public class SchedulerConfig {

@Inject
private DataSource dataSource;

@Inject
private JobsListenerService jobsListenerService;

@Bean
public JobFactory jobFactory(ApplicationContext applicationContext) {
    AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
    jobFactory.setApplicationContext(applicationContext);
    return jobFactory;
}


@Bean
public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory)
        throws IOException {
    SchedulerFactoryBean factory = new SchedulerFactoryBean();
    factory.setJobFactory(jobFactory);
    factory.setDataSource(dataSource);
    factory.setQuartzProperties(quartzProperties());
    factory.setGlobalJobListeners(jobsListenerService);
    return factory;
}

@Bean
public Properties quartzProperties() throws IOException {
    PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
    propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
    propertiesFactoryBean.afterPropertiesSet();
    return propertiesFactoryBean.getObject();
}
}

工作:

@Component
@DisallowConcurrentExecution
public class TestJob implements Job {

    private static final String PARAMETERS = "param1=abc";

    @Inject
    private JobRegistry jobRegistry;

    @Inject
    private JobLauncher jobLauncher;

    @Inject
    private JobRepository jobRepository;

    @Inject
    private JobExplorer jobExplorer;

    private JobParametersConverter jobParametersConverter = new DefaultJobParametersConverter();

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        try {
            org.springframework.batch.core.Job job = jobRegistry.getJob("Job1");
            JobParameters jobParameters = JobParametersUtil.createJobParametersWithIncrementerIfAvailable(PARAMETERS, job);
            jobLauncher.run(job, jobParameters).getId();
        } catch (NoSuchJobException | JobParametersNotFoundException | JobParametersInvalidException | JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException e) {
            e.printStackTrace();
        }
    }
}

我已经将quartz配置为使用JobStoreCMT。我必须显式声明TransactionManager并将其传递到SchedulerFactoryBean吗?非常感谢您的帮助。

共有1个答案

仲孙才捷
2023-03-14

如果你遇到和我类似或相同的问题,为了节省世界各地其他人的时间,以下是对我有效的方法。

我明确地为SchedulerFactoryBean提供了一个事务管理器。

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, PlatformTransactionManager transactionManager)
            throws IOException {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setJobFactory(jobFactory);
        factory.setDataSource(dataSource);
        factory.setTransactionManager(transactionManager);
        factory.setQuartzProperties(quartzProperties());
        factory.setGlobalJobListeners(jobsListenerService);
        return factory;
    }
 类似资料:
  • 问题内容: 我正在使用Spring注释来管理我的事务,如下所示: 我想知道如果忘记注释会发生什么: 当alertDAO实现如下时: 似乎Hibernate允许我从数据库中获取数据,即使没有注释也是如此。 这种粗心大意的后果是什么?可能发生的最坏情况是什么? 问题答案: 根据文档(Spring docs ),它仅仅是元数据,它表明方法或接口可以由“具有交易意识的”事物(例如)进行配置。 相信只有 t

  • 我知道spring-batch-admin是不推荐的。但是,我们现在不能使用spring-cloud-data-flow。是否有其他替代方案来监控和按需重启作业?

  • 该步骤的writer的逻辑非常简单:它尝试从数据库中读取一行,一旦找到该行,就更新该行。我能够通过在find方法之后设置断点来重现,手动为数据库中的行颠簸列并提交它,然后恢复。 但是,在我的步骤中取消注释重试定义后,没有尝试重试。经过一些调试后,Spring重试逻辑似乎在块的事务中;但是由于不是由编写器中的代码引发的,而是由Spring的块事务提交逻辑引发的,因此根本没有尝试重试。 当我试图在编写

  • 是否可以配置Spring批处理管理员来启动主作业和从作业。我们有一个进程作为主节点和3-4个从节点。 Spring batch admin在单独的JVM进程中运行,但所有Spring批处理作业都使用相同的批处理数据库模式。

  • 我试图将Spring引导指南中的管理事务示例扩展到两个数据源,但是@事务注释似乎只适用于其中一个数据源。 在"Application.java"中,我添加了两个数据源及其Jdbc模板的bean。在"BookingService.java"中,我使用了属于第二个数据源的JdbcTemboard。 这是我的“Application.java”: 下面是“BookingService.java”: 这些