您好,登录后才能下订单哦!
怎么理解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纳入)。
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。