【Quartz定时任务】手动修改库表qrtz_cron_triggers的cron表达式

 Quartz内部流程:

  1. 调度器启动:当调度器启动时,Quartz 从数据库中加载触发器并将它们保存在内存中。
  2. 时间计算:Quartz 根据触发器的调度规则(例如 cron 表达式)计算下一个触发时间,并将其保存在 NEXT_FIRE_TIME 字段中。
  3. 触发任务:当当前时间达到 NEXT_FIRE_TIME 时,Quartz 触发相应的任务。
  4. 更新时间:任务触发后,Quartz 更新 PREV_FIRE_TIME 为当前时间,并根据调度规则计算新的 NEXT_FIRE_TIME

方式1:

修改配置文件,重启

quartz通过动态设置配置文件实现与数据库的同步,修改配置文件后重启服务

方式2:

直接修改 qrtz_cron_triggers 表中的 cron_expression 字段。无需重启

可能不会生效,因为 Quartz 框架通常在启动时加载调度任务,并在运行时将它们缓存在内存中。因此,直接修改数据库表不会立即影响已经加载到内存中的调度任务。

重启应用程序可能会生效,也可能不生效,,表qrtz_triggers中的所有时间相关的值并没有变动,取决于qrtz_triggers的NEXT_FIRE_TIME和PREV_FIRE_TIME。

在 Quartz 中,NEXT_FIRE_TIMEPREV_FIRE_TIME 是用来记录触发器的下一次和上一次触发时间的字段。如果修改了 cron_expression,可能需要手动更新这些字段,这些字段通常是由 Quartz 自动管理的,并且通过 Quartz API 更新触发器时会自动更新。

手动修改时间(不需要重启)

表qrtz_triggers中的下一次执行的时间NEXT_FIRE_TIME和上一次执行的时间PREV_FIRE_TIME值改为0,而且执行任务后对应的相关时间值都变成了表qrtz_cron_triggers当前cronExpression值对应的时间(不会立即生效,可能会几分钟生效)。

1.修改qrtz_cron_triggers的cronExpression

UPDATE ]`qrtz_cron_triggers` SET `CRON_EXPRESSION` = '0 59 23 * * ?' WHERE `TRIGGER_NAME` = 'DockerUserNfsStoreDeductionTrigger'

2.修改下一次执行时间和上一次执行时间

UPDATE `qrtz_triggers` SET `NEXT_FIRE_TIME` = 0,`PREV_FIRE_TIME` = 0 WHERE  `TRIGGER_NAME` = 'DockerUserNfsStoreDeductionTrigger' 

过几分钟后NEXT_FIRE_TIME变为设置定时任务的时间

 NEXT_FIRE_TIME 的单位是毫秒,将1720799940000/1000=1720799940秒,转换位时间如下

 当23:59任务触发后,Quartz 更新 PREV_FIRE_TIME 为当前时间,并根据调度规则计算新的 NEXT_FIRE_TIME

注意:测试后最后再执行一次数据,恢复原来的定时任务时间

生产上不建议这么做,如果手动将 NEXT_FIRE_TIMEPREV_FIRE_TIME 修改为 0,Quartz 在下次检查触发器时可能会忽略这些任务或引发错误。Quartz 期望这些字段包含有效的时间戳,设置为 0 可能会导致意外行为

直接修改数据库字段虽然可以实现需要的效果,但应谨慎使用,因为这可能会破坏 Quartz 的内部状态一致性。更推荐使用 Quartz API 来管理和更新调度任务。

方式3:

安全触发:通过 Quartz API 来重新调度任务。

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

public class QuartzExample {
    public static void main(String[] args) throws SchedulerException {
        // 获取调度器实例
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        
        // 启动调度器
        scheduler.start();
        
        // 创建 TriggerKey
        TriggerKey triggerKey = new TriggerKey("triggerName", "triggerGroup");
        
        // 获取当前触发器
        CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        
        // 使用新的 cron 表达式创建新的触发器
        TriggerBuilder<CronTrigger> tb = oldTrigger.getTriggerBuilder();
        CronTrigger newTrigger = tb.withSchedule(CronScheduleBuilder.cronSchedule("newCronExpression")).build();
        
        // 重新调度触发器
        scheduler.rescheduleJob(triggerKey, newTrigger);
        
        // 打印新的 NEXT_FIRE_TIME 和 PREV_FIRE_TIME
        System.out.println("Next Fire Time: " + newTrigger.getNextFireTime());
        System.out.println("Previous Fire Time: " + oldTrigger.getPreviousFireTime());
        
        // 停止调度器
        scheduler.shutdown();
    }
}

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值