歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Quartz1.6有狀態JOB碰到的棘手問題既解決方案

關於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包:

  • quartz-2.0.jar,
  • slf4j-api.1.6.2.jar
  • slf4j-log4j12-1.6.2.jar
  • c3p0-0.9.1.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

Copyright © Linux教程網 All Rights Reserved