Quartz 觸發器、過期觸發策略 、排它日曆、數據持久化

目錄

Trigger 概述與常用觸發器

Trigger 常用屬性

Trigger 優先級 priority

過期觸發策略(misfire Instructions)

org.quartz.Calendar 排除日曆

SimpleTrigger 觸發器

CronTrigger 觸發器

Quartz 數據持久化


Trigger 概述與常用觸發器

1、org.quartz.Trigger 是基接口,具有所有觸發器通用的屬性,使用 org.quartz.TriggerBuilder 類實例化實際觸發器。

2、觸發器有一個關聯的 TriggerKey,它應該在單個 Scheduler 中唯一標識它們。

3、多個觸發器可以指向同一個作業(Job),但是一個觸發器只能指向一個作業。

4、觸發器可以通過 JobDataMap  放置屬性將參數/數據傳輸到 Job 。《quartz-scheduler 核心 API

//設置觸發器的啓動時間爲 30 秒後,然後每10秒執行一次任務.
Trigger trigger = TriggerBuilder.newTrigger()
		.withIdentity(TriggerKey.triggerKey("myTrigger", "myTriggerGroup"))
		.withSchedule(SimpleScheduleBuilder.simpleSchedule()
				.withIntervalInSeconds(10)
				.repeatForever())
		.startAt(DateBuilder.futureDate(30, DateBuilder.IntervalUnit.SECOND))
		.build();
org.quartz.Trigger 觸發器接口常用實現類
SimpleTrigger 簡單觸發器,在一個給定的時間時刻,並有選擇地以指定的間隔重複。使用 SimpleScheduleBuilder 構建
DailyTimeIntervalTrigger 每日間隔時間觸發器,根據每天的重複時間間隔觸發。使用 DailyTimeIntervalScheduleBuilder 構建。
CalendarIntervalTrigger 日曆觸發器,以每 N 個日曆時間單位觸發一次。使用 CalendarIntervalScheduleBuilder 構建.
CronTrigger cron 表達式觸發器,靈活指定 年月日時分秒星期。使用 CronScheduleBuilder 構建。

Trigger 常用屬性

Trigger 常用屬性
TriggerKey 標識 trigger 的身份。鍵由名稱和組構成,且名稱在組中必須唯一。TriggerKey(String name, String group),name 不能爲 null,否則拋異常,group 爲 null 時,使用默認值 “DEFAULT”。
startTime

1)設置觸發器開始的時刻,屬性值是 java.util.Date 類型,默認值爲 startTime = new Date();

2)有些類型的 trigger,會在設置的 startTime 時刻立即觸發,有些類型的 trigger,則會在 startTime 之後纔開始生效。

3)如當前系統時間爲1月3號,設置一個 trigger 在每個月的第5天執行任務,startTime 屬性設置爲 3 月 2 號,則該 trigger 第一次觸發是在3月5號,然後是 4月5號,以此類推。

endTime 設置 trigger 失效的時刻。比如 ”每月第5天執行” 的 trigger,如果其 endTime 是 6 月30 號,則其最後一次執行時間是 6 月 5 號。

Trigger  的屬性在構建 trigger 的時候可以通過 TriggerBuilder 設置,比如:

//設置觸發器的啓動時間爲 startTime,失效時間爲 endTime。
//一到啓動時間 SimpleTrigger 就會第一次執行任務,然後間隔 withIntervalInSeconds 繼續執行
//直到失效時間不再執行,觸發器也會被卸載.
Trigger trigger = TriggerBuilder.newTrigger()
		.startAt(startTime)
		.endAt(endTime)
		.withIdentity(TriggerKey.triggerKey("myTrigger", "myTriggerGroup"))
		.withSchedule(SimpleScheduleBuilder.simpleSchedule()
				.withIntervalInSeconds(10)
				.repeatForever())
		.build();

Trigger 優先級 priority

1、如果 trigger 很多,或者 Quartz 線程池的工作線程太少,Quartz 可能沒有足夠的資源同時觸發所有的 trigger,這種情況下可能希望控制哪些 trigger 優先使用 Quartz 的工作線程。

2、Trigger 的 priority 屬性用於設置優先級,比如有 30 個 trigger 需要同時觸發,但只有 15 個工作線程,此時優先級最高的 15 個 trigger 會被優先觸發。如 TriggerBuilder.newTrigger().withPriority(2).xxx;

3、如果沒有爲 trigger 設置優先級(priority ),則默認爲 5;priority 屬性值可以是任意整數,正數、負數都可以。數字越小優先級越高

4、只有同時觸發的 trigger 之間纔會比較優先級,10:59 觸發的 trigger 總是在 11:00 觸發的 trigger 之前執行。

5、如果 trigger 是可恢復的,在恢復後再調度時,優先級與原 trigger 是一樣的。

6、驗證非常簡單,減小 quartz 線程池中的線程數(quartz.properties Quartz Configuration),然後同時執行多個觸發器,觀察設置 priority 屬性的區別即可 :

#quartz 線程池中的線程個數,如 10 個線程表示最多可以同時執行10個任務/作業
org.quartz.threadPool.threadCount: 10

源碼:https://github.com/wangmaoxiong/quartzapp/blob/master/src/test/java/com/wmx/quartzapp/helloworld/HaiJobTest.java

過期觸發策略(misfire Instructions)

1、trigger 的屬性 misfireInstruction:表示如果 scheduler 關閉了,或者 Quartz 線程池中因爲當時沒有可用的線程來執行 job 而錯過觸發時間,此時持久性的 trigger 就會錯過(miss)其觸發時間,即錯過觸發(misfire)

2、不同類型的 trigger,有不同的 misfire 機制,它們默認都使用“錯過觸發智能策略(misfire_instruction_smart_policy)”,根據 trigger 的類型和配置動態調整行爲。

3、當 scheduler 啓動的時候,查詢所有錯過觸發(misfire) 的持久性 trigger,然後根據它們各自的 misfire 機制更新 trigger 的信息。

4、過期策略都定義爲了常量,彙總如下:

Trigger 接口公共過期策略
MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY = -1 忽略策略
MISFIRE_INSTRUCTION_SMART_POLICY = 0 智能策略
SimpleTrigger 觸發器過期策略
MISFIRE_INSTRUCTION_FIRE_NOW = 1 立即執行策略
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT = 2 對現有的重新開始計數執行
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT = 3 重新安排,重複計數
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT = 4 重新安排下一個,剩餘計數
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT = 5 重新安排下一步,現有計數
CronTrigger 觸發器過期策略
MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1 現在執行一次
MISFIRE_INSTRUCTION_DO_NOTHING = 2 什麼都不做
MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY = -1 忽略策略

5、misfire 策略作爲基本調度(simple schedule)的一部分進行配置(通過 XxxSchedulerBuilder 設置),如:

//創建簡單觸發器,每 30 秒觸發一次,使用 MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT 過期策略
SimpleTrigger trigger = TriggerBuilder.newTrigger()
	.startNow()
	.withIdentity(TriggerKey.triggerKey("myTrigger", "myTriggerGroup"))
	.withSchedule(SimpleScheduleBuilder.simpleSchedule()
			.withIntervalInSeconds(30)
			.repeatForever()
			.withMisfireHandlingInstructionNowWithExistingCount())
	.build();

本節源碼:SimpleTriggerTest.java

//每月1號晚上 23:30 執行一次。
//monthlyOnDayAndHourAndMinute(int dayOfMonth, int hour, int minute) :表示每月 dayOfMonth 號 hour 點 minute 分 0 秒執行一次.
//等價於 cron 表達式:String cronExpression = String.format("0 %d %d %d * ?", minute, hour,dayOfMonth);
//使用過期策略:CronTrigger.MISFIRE_INSTRUCTION_FIRE_ONCE_NOW
Trigger trigger = TriggerBuilder.newTrigger()
	.withIdentity(TriggerKey.triggerKey("myTrigger", "myTriggerGroup"))
	.withSchedule(CronScheduleBuilder.monthlyOnDayAndHourAndMinute(6, 21, 44)
			.withMisfireHandlingInstructionFireAndProceed())
	.build();

org.quartz.Calendar 排除日曆

1、org.quartz.Calendar 用於從 trigger 的調度計劃中排除時間段,比如可以創建一個 trigger,每個工作日的上午 9:30 執行,然後增加一個 Calendar,排除掉所有的商業節日。

2、可以在定義和存儲 trigger 的時候與 org.quartz.Calendar 對象進行關聯。任何實現了Calendar接口的可序列化對象都可以作爲Calendar對象。

3、Calendar 排除時間段的單位可以精確到毫秒,使用時必須先實例化,然後通過 addCalendar() 方法註冊到 scheduler。同一個Calendar 實例可用於多個 trigger。

org.quartz.Calendar 常用實現類
AnnualCalendar 年日曆,如可用於排除每年同一日期的銀行假日
CronCalendar cron 日曆,用於排除 cron 表達式指定的時間。
DailyCalendar 每日日曆,此日曆不包括每天指定的時間範圍。例如可以使用此日曆不包括每天的營業時間(上午8點至下午5點)
每個 DailyCalendar 只允許指定一個時間範圍,且該時間範圍不能跨越每日界限(即不能指定從晚上8點到早上5點)
HolidayCalendar 假日日曆,用於按天排除,如排除每個週末.
MonthlyCalendar 月日曆,用於排除一個月中的某些天
WeeklyCalendar 週日歷,用於排除一週中的某些天

3、下面以 HolidayCalendar 進行演示:

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.calendar.HolidayCalendar;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class HaiJob2Test {
    public static void main(String[] args) {
        try {
            /**1)創建調度器*/
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

            /**2)創建任務詳情*/
            JobDetail jobDetail = JobBuilder.newJob(HaiJob.class)
                    .withIdentity("haiJob2", "haiJobGroup")
                    .build();
            /**3)創建假日日曆 HolidayCalendar,精確到天,表示觸發器遇到這一天時,不觸發執行任務(放假).
             * HolidayCalendar extends BaseCalendar implements org.quartz.Calendar:假日日曆,全天被排除在日程之外,
             *      即調度器遇到這些日期就放假,不執行任務.
             * addExcludedDate(Date excludedDate):將給定日期(年月日)添加到排除日期列表中,即使設置了時分秒,也會被強制置爲 0,存放在 TreeSet<Date> 中.
             * removeExcludedDate(Date dateToRemove):移除指定假期日曆,會從 TreeSet<Date> 中進行移除.
             */
            Date excludedDate1 = new SimpleDateFormat("yyyy-MM-dd").parse("2020-04-04");
            Date excludedDate2 = new SimpleDateFormat("yyyy-MM-dd").parse("2020-04-05");
            HolidayCalendar holidayCalendar = new HolidayCalendar();
            holidayCalendar.removeExcludedDate(null);
            holidayCalendar.addExcludedDate(excludedDate1);
            holidayCalendar.addExcludedDate(excludedDate2);
            /**向調度程序添加(註冊)給定的 "日曆"
             * scheduler.addCalendar(String calName, Calendar calendar, boolean replace, boolean updateTriggers)
             * calName:假期日曆的名稱,觸發器會根據名稱進行引用、calendar:假期日曆
             * replace:表示調度器 scheduler 中如果已經存在同名的日曆是否替換
             * updateTriggers:是否更新引用了現有日曆的現有觸發器,以使其基於新觸發器是"正確的"
             * scheduler.getCalendar(String calName):根據名稱獲取調度器中註冊好的日曆
             * scheduler.getCalendarNames():獲取調度器中註冊的所有日曆的名稱.
             */
            scheduler.addCalendar("hc1", holidayCalendar, true, true);
            /**
             * 4)創建觸發器
             * withIdentity(TriggerKey triggerKey):設置觸發器的名稱以及所屬組名稱,同一組內的觸發器名稱必須唯一
             * dailyAtHourAndMinute(int hour, int minute):cron 觸發器,在每天的 hour 時 minute 分 0 秒觸發.
             * modifiedByCalendar(String calName):按日曆修改觸發器,對假期日曆 hc1 不觸發執行任務。
             */
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(TriggerKey.triggerKey("myTrigger", "myTriggerGroup"))
                    .withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(17, 18))
                    .modifiedByCalendar("hc1")
                    .build();

            //註冊任務詳情與觸發器,然後啓動調度器
            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

源碼:https://github.com/wangmaoxiong/quartzapp/tree/master/src/test/java/com/wmx/quartzapp/helloworld

SimpleTrigger 觸發器

1、SimpleTrigger 通常用於在具體的時間點執行一次,或者在具體的時間點執行,並且以指定的間隔重複執行若干次。

2、SimpleTrigger 的屬性包括:開始時間、結束時間、重複次數、重複的時間間隔。

2.1)開始時間(startTime):設置觸發器開始的時刻,屬性值是 java.util.Date 類型,默認值爲 startTime = new Date();

2.2)結束時間(endTime):結束時間屬性值會覆蓋重複次數屬性值。如設置 trigger 在終止時間之前每隔10秒執行一次,則不需要計算開始時間和終止時間之間的重複次數,只需設置終止時間並將重複次數設爲 SimpleTrigger.repeat_indefinitely=-1(當然也可以將重複次數設置爲一個教大的值,並保證該值比trigger在終止時間之前實際觸發的次數要大即可)。
2.3)重複次數(repeatCount):默認是 0、如果是常量 SimpleTrigger.REPEAT_INDEFINITELY = -1,則表示無限期循環.
2.4)重複間隔(interval):默認是 0,單位爲毫秒。注意如果重複間隔爲 0,trigger 將會以重複次數併發執行(或者以scheduler可以處理的近似併發數)。

3、SimpleTrigger 實例通過 TriggerBuilder 設置公共屬性,通過 SimpleScheduleBuilder 設置與 SimpleTrigger 相關的屬性。

4、使用 org.quartz.DateBuilder 可以非常方便地構造基於開始時間(或終止時間)的調度策略。

一:指定開始觸發時間,不重複,到點就會觸發一次:

/**
 * startAt:觸發器開始時間,不設置時,默認 startTime = new Date(),則立即會執行.
 * dateOf(int hour, int minute, int second) 返回 Date 對象,表示今天(new Date())的 hour時minute分second秒開始.
 * withIdentity(TriggerKey triggerKey):設置觸發器的名稱以及所屬組名稱,同一組內的觸發器名稱必須唯一
 */
Trigger trigger = TriggerBuilder.newTrigger()
		.startAt(DateBuilder.dateOf(15, 30, 0))
		.withIdentity(TriggerKey.triggerKey("myTrigger", "myTriggerGroup"))
		.build();

1)上面如果沒寫 startAt,則一啓動就會執行,因爲啓動時間默認爲 new Date()
2)dateOf(int hour, int minute, int second) 從源碼可知,它先是 new Date(),然後通過 java.util.Calendar 的 set 方法將時分秒設置爲 hour、minute、second,最後返回 date.

二:從指定時間開始觸發,然後每隔 5 秒執行一次,重複 10 次:

/**
 * startAt:觸發器開始時間,不設置時,默認 startTime = new Date(),則立即會執行.
 * dateOf(int hour, int minute, int second,int dayOfMonth, int month)
 *      表示 month 月 dayOfMonth 日 hour 點 minute 分 second 秒開始觸發
 * withIdentity(TriggerKey triggerKey):設置觸發器的名稱以及所屬組名稱,同一組內的觸發器名稱必須唯一
 */
Trigger trigger = TriggerBuilder.newTrigger()
		.startAt(DateBuilder.dateOf(15, 42, 0, 6, 4))
		.withIdentity(TriggerKey.triggerKey("myTrigger", "myTriggerGroup"))
		.withSchedule(SimpleScheduleBuilder.simpleSchedule()
				.withIntervalInSeconds(5)
				.withRepeatCount(10))
		.build();

在 startAt 時刻會執行第一次,然後重複執行了 10 次,所以實際上面總共是執行了 11 次任務.

三:5 分鐘以後開始觸發,每隔 10 分鐘執行一次,直到今天晚上 22:00:

/**
* startAt:觸發器開始時間,不設置時,默認 startTime = new Date(),則立即會執行.
* futureDate(int interval, IntervalUnit unit):表示未來時間,多少時間後,如 5 分鐘後,1小時後,1天后,3個月後等
* withIdentity(TriggerKey triggerKey):設置觸發器的名稱以及所屬組名稱,同一組內的觸發器名稱必須唯一
* repeatForever():方法內部是將循環次數 repeatCount=-1; 即無限循環,直到 endTime 失效時間
*/
Trigger trigger = TriggerBuilder.newTrigger()
	.startAt(DateBuilder.futureDate(5, DateBuilder.IntervalUnit.MINUTE))
	.withIdentity(TriggerKey.triggerKey("myTrigger", "myTriggerGroup"))
	.withSchedule(SimpleScheduleBuilder.simpleSchedule()
			.withIntervalInMinutes(10)
			.repeatForever())
	.endAt(DateBuilder.dateOf(22, 0, 0))
	.build();

1)IntervalUnit  是枚舉,有:MILLISECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, YEAR.
2)futureDate(int interval, IntervalUnit unit) 方法內部也是通過 java.util.Calendar 的 add 方法將指定間隔單位(unit) 加上 interval 值,最後返回 date.

四:當前時間下一個小時的整點觸發,然後每 2 小時重複一次:

/**
* startAt:觸發器開始時間,不設置時,默認 startTime = new Date(),則立即會執行.
*      evenHourDateAfterNow:表示當前時間後面最近的整點,如當前時間爲 16:20,則返回 17:00
*      evenSecondDate(Date date):也可以返回時間後面的整點,date 爲 null,默認爲 new Date();
* withIdentity(TriggerKey triggerKey):設置觸發器的名稱以及所屬組名稱,同一組內的觸發器名稱必須唯一
* repeatForever():方法內部是將循環次數 repeatCount=-1; 即無限循環.直到 endTime 失效時間
*/
Trigger trigger = TriggerBuilder.newTrigger()
	.startAt(DateBuilder.evenHourDateAfterNow())
	.withIdentity(TriggerKey.triggerKey("myTrigger", "myTriggerGroup"))
	.withSchedule(SimpleScheduleBuilder.simpleSchedule()
			.withIntervalInHours(2)
			.repeatForever())
	.build();

官網源碼:DateBuilder.java ,本節示例源碼:SimpleTriggerTest.java

CronTrigger 觸發器

1、CronTrigger 觸發器使用起來更加靈活,基本可以代替 SimpleTrigger,使用 CronScheduleBuilder 構建。

2、Cron 表達式是一個字符串,用空格隔開,分爲6或7個域,從左到右爲:秒 分 時 月份中的日期 月 星期中的日期 年份。年份可寫可不寫。

3、網上介紹  cron 表達式的文章有很多,使用  在線Cron表達式生成器 可以輕鬆生成 cron 表達式,下面簡單舉幾例:

3.1)"0/3 * * * * ?" : 每 3 秒鐘執行一次
3.2)"40 0/30 * * * ?":每 30 分鐘在第 40 秒時刻執行一次
3.3)"0 0/30 1 * * * ?":在每天凌晨 1 點內,每 30 分鐘在第 0 秒時刻執行一次
3.4)"0 30 10-13 ?* WED,FRI":每週三、週五的10:30、11:30、12:30、13:30 執行一次
3.5)"0 0/30 8-9 5,20 * ?":每月5日、20日8至10點之間每半小時觸發一次,8:00,8:30,9:00,9:30(注意10點不觸發)

3.6)星期可以指定爲1到7(1是星期日),或者字符串 SUN,MON,TUE,WED,THU,FRI,SAT
3.7)月份可以指定爲0到11,或者爲 JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC。
3.8)"?" 字符用於日期和星期字段,當其中一個有值時,另一個就設置爲 "?"
3.9)"*" 表示任意時刻

4、對於類似“每天上午9:00至10:00之間每5分鐘,下午1:00至晚上10點之間每20分鐘一次”的需求,通常直接創建兩個觸發器運行相同的作業來解決。

5、startTime 、endTime 屬於公共屬性,所有觸發器都可以進行設置。

一:每天上午 8 點至下午 5 點之間,每隔一分鐘觸發一次

//每天上午 8 點至下午 5 點之間,每隔一分鐘觸發一次,默認啓動時不會執行,啓動1分鐘後開始執行第一次
Trigger trigger = TriggerBuilder.newTrigger()
	.withIdentity(TriggerKey.triggerKey("myTrigger", "myTriggerGroup"))
	.withSchedule(CronScheduleBuilder.cronSchedule("0 0/1 8-17 * * ?"))
	.build();

二:每週一、三上午 9:30 執行一次:

//每週一、三上午9:30執行一次
Trigger trigger = TriggerBuilder.newTrigger()
	.withIdentity(TriggerKey.triggerKey("myTrigger", "myTriggerGroup"))
	.withSchedule(CronScheduleBuilder.cronSchedule("0 30 9 ? * MON,WED"))
	.build();

三:每月初一晚上 23:30 執行一次:

//每月1號晚上 23:30 執行一次。
//monthlyOnDayAndHourAndMinute(int dayOfMonth, int hour, int minute) :表示每月 dayOfMonth 號 hour 點 minute 分 0 秒執行一次.
//等價於 cron 表達式:String cronExpression = String.format("0 %d %d %d * ?", minute, hour,dayOfMonth);
Trigger trigger = TriggerBuilder.newTrigger()
	.withIdentity(TriggerKey.triggerKey("myTrigger", "myTriggerGroup"))
	.withSchedule(CronScheduleBuilder.monthlyOnDayAndHourAndMinute(1, 23, 30))
	.build();
monthlyOnDayAndHourAndMinute(int dayOfMonth, int hour, int minute) 每月幾號幾點幾分執行一次,等價:
String.format("0 %d %d %d * ?", minute, hour,dayOfMonth);
dailyAtHourAndMinute(int hour, int minute) 每天幾點幾分執行一次,等價:
String.format("0 %d %d ? * *", minute, hour)
weeklyOnDayAndHourAndMinute(int dayOfWeek, int hour, int minute) 每週幾點幾分執行一次,等價:
String.format("0 %d %d ? * %d", minute, hour,dayOfWeek);

CronTrigger  過期觸發策略(misfire Instructions)

本節源碼:CronTriggerTest.java

Quartz 數據持久化

1、org.quartz.spi.JobStore 負責跟蹤調度程序的所有"工作數據",如 jobs,triggers,Calendar 等。

JobStore 接口常用實現類
RAMJobStore 內存存儲。性能最高,程序關閉後,所有調度數據會丟失。切換 RAMJobStore,只需如下設置即可(這也是默認方式):
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore  #指定存儲方式爲 RAM 內存存儲
JobStoreTX 數據庫存儲。如果不需要將調度命令(例如添加和刪除triggers)綁定到其他事務,那麼可以通過使用 JobStoreTX 管理事務(這是最常見的選擇)。org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
JobStoreCMT 數據庫存儲。如果需要 Quartz 與其他事務(即J2EE應用程序服務器)一起工作,那麼應該使用 JobStoreCMT,這種情況下,Quartz 將讓應用程序服務器容器管理事務。org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreCMT

2、quartz 默認就是使用的內存存儲,也就是說當什麼都沒有配置的時候,它就是 RAMJobStore。《quartz-scheduler 定時器概述、核心 API 與 快速入門》中也是內存存儲。

3、《Spring Boot 2.1.3 集成 Quartz 定時器, jdbc 持久化調度信息》中使用 JobStoreTX 將數據持久化到數據庫。

quartz.properties Quartz Configuration

4、需要使用 jdbc 存儲到數據庫中,則可以參考《Spring Boot 2.1.3 集成 Quartz 定時器, jdbc 持久化調度信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章