全面學習ORACLE Scheduler特性(7)Scheduler丟擲的Events

junsansi發表於2009-08-26

四、使用Events

  Event直譯對應的中文解釋是指事件,不過單純講事件畢竟太抽象了,舉個示例來形容吧。A(對應某個應用程式,或者是ORACLE中的程式)在幹活時突然眉頭一皺說道,不好,前方有情況,這可怎麼辦!這時,只見它認真想了想,過了一會兒臉上一喜說道:有了,俗話說早請示啊晚彙報,出現情況要找領導,趕緊給領導發訊息唄!於是B(也是對應某個應用或ORACLE程式)就收到了一條A發過來的"前方有XX情況"的訊息,這個過程就叫EVENT(含A發訊息以及B接收訊息)。

  SCHEDULER 中有兩種觸發EVENT的情況:

  • Scheduler 觸發的Events

    Scheduler 中觸發的Events,一般是說當前schduler中job的狀態發生修改,類似job啟動,或者執行結束,或者達到執行時間等諸如此類的動作,都能夠丟擲一個EVENT,接收到EVENT的applicate就可以根據這些資訊進行適當的處理。

    比如說,由於系統太過於繁忙,超出job啟動時間後30分鐘,job仍然沒能順利啟動,那麼這個時候,Scheduler就可以丟擲一條EVENT給外部的應用,以便外部應用能夠及時通知DBA,進行處理。

  • application 觸發的Events

    外部的應用也可以觸發Events,並且由Scheduler來接收並處理這一型別的Events。所謂Scheduler處理EVENT就是指Scheduler啟動相應的job來執行相關操作,這類job在建立時專門宣告瞭event的處理,這樣當接收到EVENT時,這類job就會啟動。

  Scheduler 使用Oracle高階佇列來丟擲以及銷燬Events。當丟擲Schduler觸發的Events時,Scheduler將訊息入隊到預設的event佇列,application則通過檢查該佇列來處理Events。當丟擲application觸發的Events時,application將訊息入隊到處理job對應的佇列中。

  下面我們也按照這兩個型別來介紹Scheduler中的Events。

4.1 Scheduler丟擲的Events

  前面說了,Scheduler丟擲的Events一般是指job狀態改變時觸發的,那麼是不是說只要job狀態發生了改變,就會觸發Events,其實並非如此,因為預設情況下,job是不觸發Events的。

  Scheduler 中的job有一個屬性叫raise_events,專門用來設定job觸發Events的條件,該屬性在CREATE_JOB時不能執行,因此預設情況下該屬性不會賦值,自然也就不會觸發EVENT。要設定raise_events屬性,只能是在job建立完成後,通過SET_ATTRIBUTE過程修改job的raise_events屬性。

  例如,修改前面建立的job-,啟用raise_events屬性,執行語句如下:

    SQL> BEGIN

      2  DBMS_SCHEDULER.SET_ATTRIBUTE('INSERT_TEST_TBL', 'raise_events',  DBMS_SCHEDULER.JOB_ALL_EVENTS)

      3  END;

      4  /

    PL/SQL procedure successfully completed.

  上述示例中指定的raise_events屬性的屬性值DBMS_SCHEDULER.JOB_ALL_EVENTS,就是丟擲Events的觸發條件。

  觸發Events的有下列的型別,分別代表不同的操作:

  • job_started :JOB啟動;
  • job_succeeded :JOB成功結束;
  • job_failed :JOB執行失敗;
  • job_broken :JOB被置為BROKEN狀態;
  • job_completed :JOB達到最大執行次數,或者執行的結束日期;
  • job_stopped :JOB被STOP_JOB過程置為停止執行的狀態;
  • job_sch_lim_reached :Job的schedule達到限定值;
  • job_disabled :JOB被置於DISABLE狀態;
  • job_chain_stalled :執行於chain的JOB被置於CHAIN_STALLED狀態;
  • job_all_events :含上述提到的所有型別;
  • job_run_completed :由於Job執行出錯、成功結束或被手動停止。

  起用raise_events後,Scheduler就會按照設定的觸發條件,當達到觸發條件時,即會丟擲事件資訊到SYS.SCHEDULER$_EVENT_QUEUE佇列。

  例如,手動執行一次INSERT_TEST_TBL,看看是否向佇列中記錄資訊,操作如下:

    SQL> exec dbms_scheduler.run_job('INSERT_TEST_TBL');

    PL/SQL procedure successfully completed.

  執行下列指令碼,出隊資料:

    SQL> set serveroutput on

    SQL> DECLARE

      2    l_dequeue_options    DBMS_AQ.dequeue_options_t;

      3    l_message_properties DBMS_AQ.message_properties_t;

      4    l_message_handle     RAW(16);

      5    l_queue_msg          sys.scheduler$_event_info;

      6  BEGIN

      7    l_dequeue_options.consumer_name := 'TEST';

      8

      9    DBMS_AQ.dequeue(queue_name         => 'SYS.SCHEDULER$_EVENT_QUEUE',

     10                    dequeue_options    => l_dequeue_options,

     11                    message_properties => l_message_properties,

     12                    payload            => l_queue_msg,

     13                    msgid              => l_message_handle);

     14    COMMIT;

     15

     16    DBMS_OUTPUT.put_line('event_type : ' || l_queue_msg.event_type);

     17    DBMS_OUTPUT.put_line('object_owner : ' || l_queue_msg.object_owner);

     18    DBMS_OUTPUT.put_line('object_name : ' || l_queue_msg.object_name);

     19    DBMS_OUTPUT.put_line('event_timestamp: ' || l_queue_msg.event_timestamp);

     20    DBMS_OUTPUT.put_line('error_code : ' || l_queue_msg.error_code);

     21    DBMS_OUTPUT.put_line('event_status : ' || l_queue_msg.event_status);

     22    DBMS_OUTPUT.put_line('log_id : ' || l_queue_msg.log_id);

     23    DBMS_OUTPUT.put_line('run_count : ' || l_queue_msg.run_count);

     24    DBMS_OUTPUT.put_line('failure_count : ' || l_queue_msg.failure_count);

     25    DBMS_OUTPUT.put_line('retry_count : ' || l_queue_msg.retry_count);

     26  END;

     27  /

    event_type : JOB_STARTED

    object_owner : TEST

    object_name : INSERT_TEST_TBL

    event_timestamp: 25-AUG-09 12.49.29.558758 PM +08:00

    error_code : 0

    event_status : 1

    log_id :

    run_count : 1

    failure_count : 0

    retry_count : 0

    PL/SQL procedure successfully completed.

  從返回的資訊可以看到,event的型別為JOB_STARTED,表示JOB啟動。實際上job:INSERT_TEST_TBL執行一次至少會向佇列中插入兩條event資訊,一條為JOB_STARTED,一條則為JOB_SUCCEEDED(也可能是JOB_FAILED),這裡不詳細演示,感興趣的朋友不妨自行測試。

    提示:SYS.SCHEDULER$_EVENT_QUEUE佇列基於SYS.SCHEDULER$_EVENT_QTAB佇列表,因此查詢SYS.SCHEDULER$_EVENT_QTAB也可以獲取上述的資訊。

  SYS.SCHEDULER$_EVENT_QUEUE 是一個固定佇列,實際應用的過程中,DBA應該根據實際情況,將該表訪問許可權授予相關使用者,以便順利出隊該佇列中的events資訊。

  另外,友情提醒,預設情況下Scheduler僅保留最近24小時的Events資訊,如果希望修改該設定的話,可以通過SET_SCHEDULER_ATTRIBUTE過程,修改scheduler的event_expiry_time屬性,該項屬性的屬性值以秒為單位。

==============================================

全面學習ORACLE Scheduler特性(6)設定Repeat Interval引數

全面學習ORACLE Scheduler特性(5)Schedules排程Programs執行的Jobs

全面學習ORACLE Scheduler特性(4)建立和管理Schedule

全面學習ORACLE Scheduler特性(3)使用Programs

全面學習ORACLE Scheduler特性(2)管理jobs

全面學習ORACLE Scheduler特性(1)建立jobs

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7607759/viewspace-613285/,如需轉載,請註明出處,否則將追究法律責任。

相關文章