QuartzJobBean无法获取事务同步的Session

时间:2017-08-29 08:12:38

标签: java spring hibernate quartz-scheduler spring-transactions

当我运行SpringBootApplication和QuartzJobBean触发器时,我得到一个HibernateSystemException,表示Could not obtain transaction-synchronized Session for current thread。当我在第一时间搜索Exception时,我发现了很多类似的问题(在SO上)但是没有一个提供的答案帮助了我。

我的ApplicationConfig看起来像这样。在这里,我设置了TransactionManager和Datasource等。

@SpringBootApplication(scanBasePackages = {"de.xxx.yyy"}, exclude = HibernateJpaAutoConfiguration.class)
@EnableTransactionManagement
public class ApplicationConfig extends SpringBootServletInitializer {

...

    @Bean
    @Autowired
    public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
        HibernateTransactionManager txManager = new HibernateTransactionManager();
        txManager.setSessionFactory(sessionFactory);
        return txManager;
    }

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        ...
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setHibernateProperties(hibernateProperties());
        ...
    }
}

然后我有另一个Quartz配置 - QuartzSchedulerConfig。它配置触发器,详细信息和调度程序

@Configuration
@EnableTransactionManagement
public class QuartzSchedulerConfig {

    @Autowired
    DataSource dataSource;

    @Autowired
    ApplicationContext context;

    @Autowired
    QuartzTriggerProperties quartzTriggerProperties;

    @Autowired
    HibernateTransactionManager transactionManager;

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() throws ParseException, IOException {

        SchedulerFactoryBean factory = new SchedulerFactoryBean();

        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(context);
        ...
        factory.setTransactionManager(transactionManager);
        factory.setJobFactory(jobFactory);
        ...
        factory.setTriggers(collectorTrigger());
        return factory;
    }

    ...

    @Bean
    public Trigger collectorTrigger() throws ParseException {

        CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
        factoryBean.setJobDetail(collectorJobDetail());
        factoryBean.setName("collectorTrigger");
        factoryBean.setCronExpression(quartzTriggerProperties.getCollectorTrigger())
        factoryBean.afterPropertiesSet();
        return factoryBean.getObject();
    }

    @Bean
    public JobDetail collectorJobDetail() {
        JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();

        factoryBean.setJobClass(CollectorJob.class);
        factoryBean.setDurability(true);
        factoryBean.setApplicationContext(context);
        factoryBean.setName("collectorJob");
        factoryBean.afterPropertiesSet();

        return factoryBean.getObject();
    }

    ...
}

现在,当我启动Application时,CollectorJob被执行,处理它的任务,最后当它试图将TransportVO保存到数据库时,它失败并显示以下异常:

org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: 
org.springframework.orm.hibernate5.HibernateSystemException: Could not obtain transaction-synchronized Session for current thread; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread]
    at org.quartz.core.JobRunShell.run(JobRunShell.java:213)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: org.springframework.orm.hibernate5.HibernateSystemException: Could not obtain transaction-synchronized Session for current thread; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
    at org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:296)
    at org.springframework.orm.hibernate5.HibernateExceptionTranslator.convertHibernateAccessException(HibernateExceptionTranslator.java:68)
    at org.springframework.orm.hibernate5.HibernateExceptionTranslator.translateExceptionIfPossible(HibernateExceptionTranslator.java:49)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
    at de.xxx.yyy.database.jobs.TransportDAO$$EnhancerBySpringCGLIB$$27fdef97.save(<generated>)
    at de.xxx.yyy.business.services.collector.CollectorService.saveEventForTransporter(CollectorService.java:314)
    at de.xxx.yyy.business.services.collector.CollectorService.downloadAndSaveArchiv(CollectorService.java:243)
    at de.xxx.yyy.business.services.collector.CollectorService.saveArchivesToDownload(CollectorService.java:110)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:724)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
    at de.xxx.yyy.business.services.collector.CollectorService$$EnhancerBySpringCGLIB$$cdf948ab.saveArchivesToDownload(<generated>)
    at de.xxx.yyy.business.services.collector.CollectorJob.downloadArchives(CollectorJob.java:123)
    at de.xxx.yyy.business.services.collector.CollectorJob.doDownloadForAllServer(CollectorJob.java:87)
    at de.xxx.yyy.business.services.collector.CollectorJob.executeInternal(CollectorJob.java:73)
    at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
    ... 1 more
Caused by: org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
    at org.springframework.orm.hibernate5.SpringSessionContext.currentSession(SpringSessionContext.java:133)
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:719)
    at de.xxx.yyy.database.protocoll.QueryDSLSupport.getSession(QueryDSLSupport.java:35)
    at de.xxx.yyy.database.jobs.TransportDAO.save(TransportDAO.java:65)
    at de.xxx.yyy.database.jobs.TransportDAO$$FastClassBySpringCGLIB$$d4e14826.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    ... 22 more

调用TransportDAO的save-Method的Service-Method注释为@Transactional,当客户使用该应用程序时,会话获取的TransactionManagement没有问题。所以我猜测我的QuartzScheduler在某种程度上是错误配置的。我需要改变什么才能使QuartzJobs工作?

0 个答案:

没有答案