(7)使用Events之Scheduler拋出的Events |
[君三思] 2009-8-26 |
四、使用EventsEvent直譯對應的中文解釋是指事件,不過單純講事件畢竟太抽象了,舉個示例來形容吧。A(對應某個應用程序,或者是ORACLE中的進程)在干活時突然眉頭一皺說道,不好,前方有情況,這可怎么辦!這時,只見它認真想了想,過了一會兒臉上一喜說道:有了,俗話說早請示啊晚匯報,出現情況要找領導,趕緊給領導發消息唄!于是B(也是對應某個應用或ORACLE進程)就收到了一條A發過來的"前方有XX情況"的消息,這個過程就叫EVENT(含A發消息以及B接收消息)。 SCHEDULER 中有兩種觸發EVENT的情況:
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的有下列的類型,分別代表不同的操作:
起用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 是一個固定隊列,實際應用的過程中,DBA應該根據實際情況,將該表訪問權限授予相關用戶,以便順利出隊該隊列中的events信息。 另外,友情提醒,默認情況下Scheduler僅保留最近24小時的Events信息,如果希望修改該設置的話,可以通過SET_SCHEDULER_ATTRIBUTE過程,修改scheduler的event_expiry_time屬性,該項屬性的屬性值以秒為單位。 |