温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么理解Quartz 中的JobStore接口

发布时间:2021-11-16 09:58:47 来源:亿速云 阅读:135 作者:柒染 栏目:大数据

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

  • 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纳入)。

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

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI