Quartz持久化数据库及遇到的问题

一、为什么要持久化?

网上大多数的Quartz Demo都不是持久化的,都是存储在内存里面的。当程序突然被中断时,如断电,内存超出时,很有可能造成任务的丢失,为了解决这种情况,我们可以将调度信息存储到数据库里面,进行持久化,当程序被中断后,再次启动,仍然会保留中断之前的数据,继续执行,而并不是重新开始。

二、Quartz 两种存储类型

在这里插入图片描述

三、关于两种存储类型的配置

1、依赖文件

<!--  SpringBoot整合Quartz依赖  -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-quartz</artifactId>
       </dependency>
 
<!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
 
   <!--   jdbc_starter     -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
 
    <!--   druid_stater     -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>

2、 RAMJobStore
在application.yml文件中进行如下配置即可,启动项目后定时任务就可以正常运行。
在这里插入图片描述

3、JobStroeTX
1、创建SchedulerConfig文件

@Configuration
public class ScheduleConfig {
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
 
        factory.setDataSource(dataSource);
 
        //quartz参数
        Properties prop = new Properties();
        prop.put("org.quartz.scheduler.instanceName", "quartzScheduler");
        prop.put("org.quartz.scheduler.instanceId", "AUTO");
        //线程池配置
        prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        prop.put("org.quartz.threadPool.threadCount", "20");
        prop.put("org.quartz.threadPool.threadPriority", "5");
        //JobStore 配置
       // prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
        prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore");
        //集群配置
        prop.put("org.quartz.jobStore.isClustered", "false");
        prop.put("org.quartz.jobStore.misfireThreshold", "12000");
        prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
        factory.setQuartzProperties(prop);
 
        factory.setSchedulerName("DemoScheduler");
        //延时启动
        factory.setStartupDelay(30);
        factory.setApplicationContextSchedulerContextKey("applicationContextKey");
        //可选 QuartzScheduler 启动更新已存在的Job
        factory.setOverwriteExistingJobs(true);
        //设置自动重启,默认为true
        factory.setAutoStartup(true);
        return factory;
    }
 
    @Bean(name = "scheduler")
    public Scheduler scheduler(DataSource dataSource) throws SchedulerException {
 
        return  schedulerFactoryBean(dataSource).getScheduler();
    }
}

2、在Service 层 注入 Scheduler即可。启动项目后定时任务就可以正常运行。

@Autowired
private Scheduler scheduler;

四、采用Qutarz持久化时遇到的坑

1、Caused by: org.quartz.SchedulerConfigException: DataSource name not set.
在这里插入图片描述

   原因是 spring-boot-starter-parent 的版本问题导致的,spring-boot-starter-parent 版本不一样引用的 quartz的默认数据源的路径也发生了改变。
     解决办法如下:

如果 spring-boot-starter-parent 的版本为 2.5.6 之后的版本 在 定时任务JDBC配置文件中应该修改如下操作

prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore");

如果 spring-boot-starter-parent 的版本为 2.5.6 之前的版本 在 定时任务JDBC配置文件中应该修改如下操作

 prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");

2、Quartz调度程序作业未存储到数据库中

  明明在项目中已经将  Quartz 数据库持久化配置完毕,每次添加定时任务时,任务添加成功且到达定时时间后,任务会被执行,但是任务却没有写入数据库。检查代码后,发现Scheduler注入的问题,因为项目中一直用的是默认的DefaultQuartzScheduler,也就意味着一直都是用的内存方式存储的数据,所以任务永远不会被写入数据库。

错误的写法:

SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler =  factory.getScheduler();

正确的写法(在定时任务的配置文件中加入如下的写法即可):


@Bean(name = "scheduler")
   public Scheduler scheduler(DataSource dataSource) throws SchedulerException {
 
       return  schedulerFactoryBean(dataSource).getScheduler();
   }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值