怎么理解Quartz中的JobStore接口

怎么理解Quartz 中的JobStore接口,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

成都创新互联公司制作网站网页找三站合一网站制作公司,专注于网页设计,成都网站设计、做网站、成都外贸网站建设公司,网站设计,企业网站搭建,网站开发,建网站业务,680元做网站,已为上千家服务,成都创新互联公司网站建设将一如既往的为我们的客户提供最优质的网站建设、网络营销推广服务!

  • org.quartz.spi.JobStore 是任务存储的顶层接口类

  • org.quartz.simpl.RAMJobStore 是内存存储机制实现类

  • org.quartz.impl.jdbcjobstore.JobStoreSupport 是基于JDBC数据库存储的抽象类

  • org.quartz.impl.jdbcjobstore.JobStoreCMT 是受应用容器管理事物的数据库存储实现类

  • org.quartz.impl.jdbcjobstore.JobStoreTX 是不受应用容器事物管理的数据库存储实现类

org.quartz.jobStore.class = 上面提到的具体实现类

在quzrtz.properties 中配置以上代码来告诉quartz我们使用何种存储机制

存储机制对比

内存存储机制
org.quartz.simpl.RAMJobStore
使用内存存储的优点是任务的存储和读取的速度极快,和数据库持久化相比差别还是非常大的,而且框架搭建简单,开箱即用。它的缺点是当Quartz程序或应用程序停止了,伴随在内存中的数据也会被回收,任务等数据就永久丢失了。
数据库存储机制
org.quartz.impl.jdbcjobstore.JobStoreTX
TX就是事物的意思,此存储机制用于Quartz独立于应用容器的事物管理,如果是Tomcat容器管理的数据源,那我们定义的事物也不会传播给Quartz框架内部。通俗的讲就是不管我们的Service服务本身业务代码是否执行成功,只要代码中调用了Quartz API的数据库操作,那任务状态就永久持久化了,就算业务代码抛出运行时异常任务状态也不会回滚到之前的状态。

org.quartz.impl.jdbcjobstore.JobStoreCMT
CMT的全称是Container Managed Transactions,表示容器管理事物,也就是让应用容器托管事物。这里假设应用容器是Tomcat,并且项目和Quartz都是使用Tomcat配置的数据源,那么项目和Quartz的代码中就可以共用同一个事物,不管是业务代码还是Quartz内部抛出异常,Service服务内的所有数据操作都会回滚到原始状态。JobStoreCMT和JobStoreTX最大的区别是JobStoreCMT需要配置两个数据源,一个是受应用容器管理的数据源,还有一个是不受应用容器管理的数据源。
这里需要想一想为什么需要两个数据源?
我个人的理解是不受应用容器管理的数据源用来由Quartz内部进行"增删改查",假如一个触发器已失效,那么Quartz框架内部就会自动删除这个触发器并提交事物,而无需开发人员的项目代码来处理,全由Quartz内部管理。

选用哪种存储方式

        什么情况下使用RAMJobStore内存存储方式呢?

  根据开发中的使用经验,发现有些任务是随着项目启动而启动的,就算项目关闭或系统宕机,那也没关系,因为项目重新启动后此任务又会随之启动。如果项目中只存在这类任务,那么就可以用内存存储。随着项目启动有几种常用的实现方式,第一种是通过实现ServletContextListener监听器接口,然后在接口实现类的contextInitialized()方法中编写启动Job的硬编码;第二种是通过Quartz的XML配置文件启动任务。

        什么情况下使用JobStoreTX数据库存储方式呢?

 使用这种方式需要注意的是,如果在一个业务代码中需要创建一个Job,那么请把创建Job的代码编写在服务代码的最后面,确保业务代码运行成功并且没有抛异常再去启动Job,如果启动Job失败的时候请抛出一个运行时异常使业务代码进行回滚。
例子:

@Transactional
public void demoService(TaskStore taskStore) {
    // 先执行插入业务操作
    taskStoreService.insert(taskStore);
    // 再执行更新业务操作
    taskDetailService.update(taskDetail);
    // 最后启动定时任务
    QuartzUtils.addJob("testName", DemoJob.class, "0 * * * * * ?");
}

注意例子中的addJob()方法中捕获了异常后进行重新封装再抛出运行时异常的,目的是Quartz内部错误时确保业务代码回滚。

        什么情况下使用JobStoreCMT数据库存储方式呢?

  JobStoreCMT和JobStoreTX的区别前文已经介绍了,在实际开发的过程中我还没有在项目中使用过此种方式。一般情况下都是使用的JobStoreTX。如果大家的项目中有着严格的事物管理,那么建议使用JobStoreCMT存储方式。

@Component
public  class JobFactory extends AdaptableJobFactory {
    @Autowired
    private AutowireCapableBeanFactory  capableBeanFactory;
    @Override
    protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
        // 调用父类的方法
        Object jobInstance = super.createJobInstance(bundle);
        // 进行注入
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}

这个类的作用就是讲Job的实例化交给IOC去进行。
其实问题在于:
Job对象的实例化过程是在Quartz中进行的,注入的实体类是在Spring容器当中的 所以在job中无法注入Srping容器的实体类。
解决方案:将Job Bean也纳入到Spring容器的管理之中,Spring容器自然能够为Job Bean自动装配好所需的依赖。
如何纳入:Job的创建都是通过JobFactory创建的。

官网解释为证:
翻译:JobFactory负责生成Job类的实例。
JobFactory 有2个实现类:AdaptableJobFactory 和 SimpleJobFactory。
自定义的工厂类 JobFactory 继承 AdaptableJobFactory 。
通过调用父类 AdaptableJobFactory 的方法createJobInstance来实现对Job的实例化。
在Job实例化完以后,再调用自身方法为创建好的Job实例进行属性自动装配并将其纳入到Spring容器的管理之中。(通过AutowireCapableBeanFactory纳入)。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。


文章名称:怎么理解Quartz中的JobStore接口
标题来源:http://hbruida.cn/article/pjpsoo.html