2012-05-29 69 views
3

我使用石英,Spring和Hibernate作为JPA提供程序。数据库是Oracle。Quartz with Spring not commiting

我有一个方法,它将文件写入文件系统并用细节更新数据库。 这种方法可以称为有两种方式:

  1. 使用Web服务
  2. 或者,作为计划quatrz工作。

    <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管理的事务:

我已经为建立石英。

问题是石英调度程序调用此方法时,文件被创建但数据库未更新(应更新两个表和一个表插入)。

我也启用了hibernate show_SQL,但是在调度程序的情况下,没有更新\ insert语句正在被记录。

虽然此方法由Web服务请求调用时可以正常工作。日志还显示update \ insert语句。

更新1

要总结一下我的问题,这就是我想实现:

  1. 创建雇员表的新纪录。
  2. 将job_id保存在job_store(石英)中。
  3. 当触发器被触发时,石英返回employee_id
  4. 基于此密钥检索(加载)员工记录。
  5. 员工发送一封电子邮件
  6. 更新通知与地位“已发送”(INSERT语句)

最后,我希望所有的表进行更新。

当石英触发作业时,所有工作除了第6点。 代码正确,因为当我使用Web服务调用调用此方法时,表正在更新。

更新2

我更新的代码使用

<prop key="org.quartz.jobStore.class">org.springframework.scheduling.quartz.LocalDataSourceJobStore</prop> 

但这也doest'nt帮助。

请帮忙。谢谢。 阿迪

回答

2

石英运行在自己的范围内,即使开始由Spring便捷的方法,所以你其实并不最终得到你的整个Spring应用程序上下文,除非你明确地在JobDataMap在豆通过(见http://forum.springsource.org/showthread.php?76974-Why-autowired-doesn-t-work-on-a-QuartzJobBean-bean )。所以,你可以传递Spring管理的bean,但是如果你不需要Quartz的全部功能,那看起来有点混乱。

如果您的调度需求并不那么复杂,那么您可能需要考虑使用Spring注释(see here),因为整个方法调用本身在Spring上下文中发生,并且您的事务将会像他们一样工作在Web服务调用中。

+0

谢谢,但作业正在从调度程序正确地从数据库检索。 JobMap包含'User'表的primayKey,并且在使用此密钥调用加载后填充User类。这是'合并',不起作用。这就是为什么我说我无法在日志中看到“插入”SQL。我可以看到所有正确的'select'语句。 – adi

+0

我同意亚伦,但如果你仍然想使用石英确保Entitymanager正确传递给石英工作。 – ayengin

1

这里有两个点来检查:

  • 该数据源必须是一个非XA数据源。如果您正在使用Java EE应用程序服务器中的连接池,那么您拥有XA数据源的可能性很高。将该数据源配置为非XA(如果您的应用程序设置和服务器允许)或创建另一个非XA数据源并将其传递到nonTransactionalDataSource属性。如果您使用nonTransactionalDataSource属性,请注意保留dataSource属性集。如果不设置(事务性)dataSource,则无法定义nonTransactionalDataSource

  • 确保您的代码真的在Spring事务中运行。使用SchedulerFactoryBeanschedulerContextAsMap属性将您的bean注入到Quartz作业中。如果您运行使用@Transactional标注的代码,则需要自动布线。如果您对该bean的实例化进行硬编码,则Spring将无法应用@Transactional注释并且默默忽略它。

此外,删除org.quartz.jobStore.class属性。在任何情况下,SchedulerFactoryBean都会覆盖该设置。它提出了一个LocalDataSourceJobStore,如果工厂的新版本决定放置别的东西,它可能会引起混淆。

最后但并非最不重要我想知道如果您可能忽略了任何异常记录在某处?确保您正在监视来自应用程序服务器的所有Spring日志消息和所有错误消息。