SpringBoot 集成 Quartz + MySQL

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: SpringBoot 集成 Quartz + MySQL

Quartz 简单使用

Java SpringBoot 中,动态执行 bean 对象中的方法

源代码地址 => https://gitee.com/VipSoft/VipBoot/tree/develop/vipsoft-quartz

工作原理解读

只要配置好 DataSource Quartz 会自动进行表的数据操作,

添加 Quartz Job 任务

保存 QRTZ_JOB_DETAILS、QRTZ_TRIGGERS => QRTZ_CRON_TRIGGERS

public void addJob(QuartzJob job) throws SchedulerException {
  ....
  JobDetail jobDetail = JobBuilder.newJob(jobClass)
                    .withIdentity(jobKey)
                    .build();
  // 放入参数,运行时的方法可以获取
  jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job);
  //该行代码执行后,会将定时任务插入 QRTZ_JOB_DETAILS 等相关表
  scheduler.scheduleJob(jobDetail, trigger);
  ....
}
//org.quartz.impl.jdbcjobstore.JobStoreSupport
public void storeJobAndTrigger(final JobDetail newJob, final OperableTrigger newTrigger) throws JobPersistenceException {
    this.executeInLock(this.isLockOnInsert() ? "TRIGGER_ACCESS" : null, new JobStoreSupport.VoidTransactionCallback() {
        public void executeVoid(Connection conn) throws JobPersistenceException {
            JobStoreSupport.this.storeJob(conn, newJob, false);  //数据保存 QRTZ_JOB_DETAILS 表
            JobStoreSupport.this.storeTrigger(conn, newTrigger, newJob, false, "WAITING", false, false); //数据保存 QRTZ_TRIGGERS 表
        }
    });
}
public int insertTrigger(...){
 INSERT_TRIGGER
 insertExtendedTriggerProperties => INSERT_CRON_TRIGGER OR INSERT_BLOB_TRIGGER
}

详见:org.quartz.impl.jdbcjobstore.StdJDBCDelegate

将 job.getJobDataMap(),对像序列化后,存入 JOB_DETAILS.JOB_DATA字段,可以是一个对像,以执行定时任务时,会把该字段反序列化,根据前期设定的内容进行业务处理

获取 Quartz Job 任务

执行计划任务时,获取 Job Detail

QuartzSchedulerThread.run()
=> qsRsrcs.getJobStore().acquireNextTriggers()
=> txCallback.execute(conn)
=> JobStoreSupport.acquireNextTriggers()
=> JobStoreSupport.retrieveJob()
=> StdJDBCDelegate.selectJobDetail()

删除 Quartz Job 任务

/**
 * <p>
 * Delete the base trigger data for a trigger.
 * </p>
 * 
 * @param conn
 *          the DB Connection
 * @return the number of rows deleted
 */
public int deleteTrigger(Connection conn, TriggerKey triggerKey) throws SQLException {
    PreparedStatement ps = null;
    deleteTriggerExtension(conn, triggerKey);
    
    try {
        ps = conn.prepareStatement(rtp(DELETE_TRIGGER));
        ps.setString(1, triggerKey.getName());
        ps.setString(2, triggerKey.getGroup());
        return ps.executeUpdate();
    } finally {
        closeStatement(ps);
    }
}

清除数据

/**
 * 清任务顺序
 */
public void clearData(Connection conn)
    throws SQLException {
    PreparedStatement ps = null;
    try {
        ps = conn.prepareStatement(rtp(DELETE_ALL_SIMPLE_TRIGGERS));
        ps.executeUpdate();
        ps.close();
        ps = conn.prepareStatement(rtp(DELETE_ALL_SIMPROP_TRIGGERS));
        ps.executeUpdate();
        ps.close();
        ps = conn.prepareStatement(rtp(DELETE_ALL_CRON_TRIGGERS));
        ps.executeUpdate();
        ps.close();
        ps = conn.prepareStatement(rtp(DELETE_ALL_BLOB_TRIGGERS));
        ps.executeUpdate();
        ps.close();
        ps = conn.prepareStatement(rtp(DELETE_ALL_TRIGGERS));
        ps.executeUpdate();
        ps.close();
        ps = conn.prepareStatement(rtp(DELETE_ALL_JOB_DETAILS));
        ps.executeUpdate();
        ps.close();
        ps = conn.prepareStatement(rtp(DELETE_ALL_CALENDARS));
        ps.executeUpdate();
        ps.close();
        ps = conn.prepareStatement(rtp(DELETE_ALL_PAUSED_TRIGGER_GRPS));
        ps.executeUpdate();
    } finally {
        closeStatement(ps);
    }
}

Demo 代码

MySQL 脚本

https://github.com/quartz-scheduler/quartz/blob/v2.3.2/quartz-core/src/main/resources/org/quartz/impl/jdbcjobstore/tables_mysql.sql

清除数据

DELETE FROM qrtz_simple_triggers ;
DELETE FROM qrtz_simprop_triggers ;
DELETE FROM qrtz_cron_triggers ;
DELETE FROM qrtz_blob_triggers ;
DELETE FROM qrtz_triggers ;
DELETE FROM qrtz_job_details ;
DELETE FROM qrtz_calendars ;
DELETE FROM qrtz_paused_trigger_grps ; 
DELETE FROM qrtz_scheduler_state ; 
DELETE FROM qrtz_locks ; 
DELETE FROM qrtz_fired_triggers

Pom.xml

如果SpringBoot版本是2.0.0以后的,则在spring-boot-starter中已经包含了quart的依赖,则可以直接使用spring-boot-starter-quartz依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<!--Quartz 集成需要和数据库交互-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.0.8</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.20</version>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!--hutool 工具类-->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.3.7</version>
</dependency>

QuartzJob 参考上图,建立实体

点击查看代码

核心代码:QuartzJobServiceImpl

点击查看代码

ScheduleConfig

点击查看代码

暂停后,qrtz_triggers 表的 TRIGGER_STATE = PAUSED

运行效果

http://localhost:8088/schedule/add

http://localhost:8088/schedule/pause

http://localhost:8088/schedule/restart

{"jobName":"测试","jobGroup":"DEFAULT","invokeTarget":"scheduletask.execute('VipSoft Quartz')","cronExpression":"0/10 * * * * ?","misfirePolicy":2,"concurrent":1,"status":"0"}

参考

实现方式参考:若依(RuoYi),他是新建了一张中间表,通过 init() 方法,利用中心中间表进行定时任务的初始化

/**
 * 项目启动时,初始化定时器 
 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据)
 */
@PostConstruct
public void init() throws SchedulerException, TaskException
{
    scheduler.clear();
    List<SysJob> jobList = jobMapper.selectJobAll();
    for (SysJob job : jobList)
    {
        ScheduleUtils.createScheduleJob(scheduler, job);
    }
}
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
12天前
|
Java 关系型数据库 MySQL
SpringBoot 通过集成 Flink CDC 来实时追踪 MySql 数据变动
通过详细的步骤和示例代码,您可以在 SpringBoot 项目中成功集成 Flink CDC,并实时追踪 MySQL 数据库的变动。
104 43
|
30天前
|
Cloud Native 关系型数据库 MySQL
无缝集成 MySQL,解锁秒级数据分析性能极限
在数据驱动决策的时代,一款性能卓越的数据分析引擎不仅能提供高效的数据支撑,同时也解决了传统 OLTP 在数据分析时面临的查询性能瓶颈、数据不一致等挑战。本文将介绍通过 AnalyticDB MySQL + DTS 来解决 MySQL 的数据分析性能问题。
|
2月前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
125 1
|
2月前
|
Java 关系型数据库 MySQL
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
80 5
|
3月前
|
关系型数据库 MySQL PHP
PHP与MySQL的无缝集成:构建动态网站的艺术####
本文将深入探讨PHP与MySQL如何携手合作,为开发者提供一套强大的工具集,以构建高效、动态且用户友好的网站。不同于传统的摘要概述,本文将以一个生动的案例引入,逐步揭示两者结合的魅力所在,最终展示如何通过简单几步实现数据驱动的Web应用开发。 ####
|
3月前
|
分布式计算 关系型数据库 MySQL
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型 图像处理 光通信 分布式计算 算法语言 信息技术 计算机应用
80 8
|
3月前
|
SQL 前端开发 关系型数据库
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
99 9
|
4月前
|
Java Maven Docker
gitlab-ci 集成 k3s 部署spring boot 应用
gitlab-ci 集成 k3s 部署spring boot 应用
|
3月前
|
消息中间件 监控 Java
您是否已集成 Spring Boot 与 ActiveMQ?
您是否已集成 Spring Boot 与 ActiveMQ?
77 0
|
7月前
|
监控 druid Java
spring boot 集成配置阿里 Druid监控配置
spring boot 集成配置阿里 Druid监控配置
350 6

热门文章

最新文章