我使用quartz,Spring和Hibernate作为JPA提供者。数据库是Oracle。
我有一个方法可以将文件写入文件系统并使用详细信息更新数据库。 可以通过两种方式调用此方法:
我将石英设置为:
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false" scope="singleton">
<property name="autoStartup" value="true"/>
<property name="waitForJobsToCompleteOnShutdown" value="true"/>
<property name="overwriteExistingJobs" value="true"/>
<property name="dataSource" ref="dataSource"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceName">FileScheduler</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.jobStore.misfireThreshold">6000</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">${driverDelegateClass}</prop>
<prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<prop key="org.quartz.threadPool.threadCount">5</prop>
<prop key="org.quartz.threadPool.threadPriority">5</prop>
</props>
</property>
</bean>
此方法使用spring managed transaction。
问题是当石英调度程序调用此方法时,会创建文件但不更新数据库(应该更新两个表并插入一个表)。
我也启用了hibernate show_SQL,但是在调度程序的情况下没有更新\ insert语句被记录。
虽然这可以通过Web服务请求调用此方法。日志也显示更新\插入语句。
更新1
总结一下我的问题,这就是我想要实现的目标:
最后,我希望更新所有表格。
当石英触发工作时,除了第6点之外,所有工作都在。 代码是正确的,因为当我使用Web服务调用调用此方法时,表格正在更新。
更新2
我更新了代码以使用
<prop key="org.quartz.jobStore.class">org.springframework.scheduling.quartz.LocalDataSourceJobStore</prop>
但这也没有帮助。
请帮忙。谢谢。 阿迪
答案 0 :(得分:3)
Quartz在它自己的上下文中运行,即使是由Spring方法启动的,所以你实际上并没有最终获得整个Spring应用程序上下文,除非你明确地在JobDataMap
传入bean(参见http://forum.springsource.org/showthread.php?76974-Why-autowired-doesn-t-work-on-a-QuartzJobBean-bean)。所以,你可以传入Spring管理的bean,但是如果你不需要Quartz的全部功能,这一切看起来都很麻烦。
如果您的调度需求不是那么复杂,您可能需要考虑使用@Scheduled
Spring注释(see here),因为整个方法调用本身就在Spring上下文中发生,而您的然后,事务将像在Web服务调用中一样工作。
答案 1 :(得分:1)
以下两点要检查:
数据源必须是非XA数据源。如果您正在使用来自Java EE应用程序服务器的连接池,那么您拥有XA数据源的可能性很高。将该数据源配置为非XA(如果您的应用程序设置和服务器允许)或创建第二个非XA数据源并将其传递到nonTransactionalDataSource
属性。如果使用nonTransactionalDataSource
属性,可能会有一点小问题 - 请记住保持dataSource
属性集。如果不设置(事务性)nonTransactionalDataSource
,也无法定义dataSource
。
确保您的代码真正在Spring事务中运行。使用schedulerContextAsMap
的{{1}}属性将bean注入Quartz作业。如果您运行使用SchedulerFactoryBean
注释的代码,则需要自动装配。如果您对该bean的实例化进行硬编码,Spring将无法应用@Transactional
注释并静默忽略它。
此外,删除@Transactional
属性。在任何情况下,org.quartz.jobStore.class
都将覆盖该设置。它会放一个SchedulerFactoryBean
,如果工厂的新版本决定放入别的东西,它可能会让人感到困惑。
最后但并非最不重要的是,我想知道您是否可能忽略了某处被记录的异常?确保您正在监视所有Spring日志消息以及来自应用程序服务器的所有错误消息。
答案 2 :(得分:-4)