關於Quartz,我想不要多做介紹了,凡是接觸JAVA調度的都會知道這個開源的調度框架.本文就重點說下Quartz中有狀態JOB的使用心得.因為我感覺國內的有狀態JOB相關的資料比較少,所以在此提供一部分個人的一點經驗.主要是針對使用quartz1.6的有狀態JOB可能出現的一個棘手問題.
1.關於有狀態JOB(StatefulJob)
網上有很多關於有狀態JOB的作用與使用的文章,我借鑒下,做下簡單的說明:
a). 實現有狀態JOB只需要實現org.quartz.StatefulJob 接口即可,StatefulJob 接口僅僅是擴展了 Job 接口,未加入新的方法.
b). Job(無狀態)和 StatefulJob 在框架中使用中存在兩個關鍵差異。首先,JobDataMap 在每次執行之後重新持久化到 JobStore 中。這樣就確保你對 Job 數據的改變直到下次執行仍然保持著。你可以在有狀態 Job 中簡單的通過 map 的 put() 方法來修改 JobDataMap.已存在的任何數據會被新的數據覆蓋掉。你也能對無狀態的 Job 這麼做,但是因為對於無狀態 Job 來說,JobDataMap 不會持久化,所以數據不會保存下來。
c). 兩個或多個有狀態的 JobDetail 實例不能並發執行。說的是你創建並注冊了一個有狀態 JobDetail 到 Scheduler 上。你還建立了兩個 Trigger 來觸發這個 Job:一個每五分鐘觸發,另一個也是每五分钏觸發。假如這兩個 Trigger 試圖在同一時刻觸發 Job,框架是不允許這種事情發生的。第二個 Trigger 一直會被阻塞直到第一個結束。
--------------------------------------分割線 --------------------------------------
先在在附件裡附上quartz2.0需要的jar包,和quartz2.0的docs即sql腳本。
FTP地址:ftp://ftp1.linuxidc.com
用戶名:ftp1.linuxidc.com
密碼:www.linuxidc.com
在 2014年LinuxIDC.com\9月\Quartz1.6有狀態JOB碰到的棘手問題既解決方案
下載方法見 http://www.linuxidc.com/Linux/2013-10/91140.htm
必須的JAR包:
--------------------------------------分割線 --------------------------------------
Spring集成Quartz定時任務框架介紹和Cron表達式詳解 http://www.linuxidc.com/Linux/2013-03/81947.htm
Spring整合Quartz http://www.linuxidc.com/Linux/2012-12/75284.htm
Spring的Quartz定時器同一時刻重復執行二次的問題解決 http://www.linuxidc.com/Linux/2012-11/73443.htm
Spring 定時器Quartz的用法 http://www.linuxidc.com/Linux/2012-11/73442.htm
--------------------------------------分割線 --------------------------------------
2.使用有狀態JOB可能碰到的棘手問題(我目前所碰到的)
在使用quartz1.6版本的時候,我碰到過比較麻煩的問題,後來在iteye和csdn求助都沒有解決.還是從國外的文章上找到了一些眉目解決了.
在實現SteafulJob接口後,該JOB怎麼搞都只執行一次.
public class SimpleJob implements StatefulJob {
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("begin execute...");
System.out.println("end execute...");
}
}
public static void main(String [] args) {
try{
Scheduler scher = StdSchedulerFactory.getDefaultScheduler(); Calendar cal = Calendar.getInstace();
cal.add(Calendar.SECOND,1);
Trigger trigger = new SimpleTrigger("JD","JD",cal.getTime (),null,5,3000L);
JobDetail jobDetail = new JobDetail("JD","JD",SimpleJob.class);
scher.scheduleJob(jobDetaill,trigger);
scher.start();
}catch(Exception ex){
ex.printStackTrade();
}
}
後來發現,每次調度啟動執行一次後,quartz的記錄觸發器狀態的表就會顯示該觸發器的狀態為:ERROR.
於是從這上面下功夫,還是久久不能解決,然後求助網絡.後來嘗試了2個方案,終於解決了.
方案一: 國內網站的一個解決方案,說是2個或多個項目使用同一個quartz數據源,會產生沖突出現上述問題,突然想起公司的quartz數據源好像是有2-3個項目連著.結果修改了其他2個項目的quartz數據源,只讓我正在弄的項目連接quartz數據源,一樣沒能解決,只能作罷.估計我出現的問題和這位總結者的問題不一樣.
方案二:這是從國外網站看到的一個方案,屬於換血型的改動,風險也還是有的.就是進行版本遷移.Quartz1.6及以下版本存在著一些不穩定的狀況,具體什麼狀況我沒驗證過.但是我是實在不知道怎麼下手了,就嘗試著將Quartz換成方案中所說的穩定性很不錯的版本:2.0版本.然後進行測試,問題就解決了.
Quartz2.0版本作為目前quartz最穩定的版本,還是值得使用的.不過中間的API變動相當大.我列出一些不同的地方.
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-09/107005p2.htm