昨天一個朋友問我如何監測一個PL/SQL的健全狀態,這裡簡單介紹幾種方法。
介紹更專業的DBMS_PIPE實現方式。
如果覺得DBMS_APPLICATION_INFO包還不夠專業,這裡再介紹一篇更加PROFESSIONAL的解決方案,通過DBMS_PIPE實現處理序間通訊。
利用這種方法,進行操作的PL/SQL過程可以通過管道發送訊息給接收進程。下面給出一個最簡單的例子:
SQL> CREATE TABLE T_RECORD
2 (STR VARCHAR2(30),
3 TIME DATE);
表已建立。
建立一個記錄表。
隨後,負責監測的進程啟動一個PIPE,然後定時檢測PIPE中是否存在資料:
SQL> DECLARE
2 V_RETURN NUMBER;
3 V_STR VARCHAR2(32767);
4 BEGIN
5 V_RETURN := DBMS_PIPE.CREATE_PIPE('P_TEST');
6 WHILE (V_RETURN = 0) LOOP
7 V_RETURN := DBMS_PIPE.RECEIVE_MESSAGE('P_TEST', 360);
8 IF V_RETURN = 0 THEN
9 DBMS_PIPE.UNPACK_MESSAGE(V_STR);
10 INSERT INTO T_RECORD VALUES (V_STR, SYSDATE);
11 END IF;
12 END LOOP;
13 V_RETURN := DBMS_PIPE.REMOVE_PIPE('P_TEST');
14 END;
15 /
需要注意,正常情況下,很可能這個PL/SQL一直處於監測狀態,不過這就需要修改過程使得過程中提交事務。
更多精彩內容:http://www.bianceng.cn/database/Oracle/
當前例子為了簡單,設定了10分鐘的到期時間,確保要監控的PL/SQL發訊息的時間間隔小於10分鐘。在這10分鐘內,在另外的會話運行PL/SQL代碼:
SQL> DECLARE
2 V_STR VARCHAR2(4000) := 'STEP BEGIN';
3 V_RETURN NUMBER;
4 BEGIN
5 DBMS_PIPE.PACK_MESSAGE(V_STR);
6 V_RETURN := DBMS_PIPE.SEND_MESSAGE('P_TEST');
7 DBMS_LOCK.SLEEP(60);
8 V_STR := 'STEP MIDDLE';
9 DBMS_PIPE.PACK_MESSAGE(V_STR);
10 V_RETURN := DBMS_PIPE.SEND_MESSAGE('P_TEST');
11 DBMS_LOCK.SLEEP(60);
12 V_STR := 'STEP END';
13 DBMS_PIPE.PACK_MESSAGE(V_STR);
14 V_RETURN := DBMS_PIPE.SEND_MESSAGE('P_TEST');
15 END;
16 /
PL/SQL過程已成功完成。
當這個代碼運行結束10分鐘後,前面監測過程由於逾時退出運行,這時檢查日誌資訊:
PL/SQL過程已成功完成。
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
會話已更改。
SQL> SELECT * FROM T_RECORD;
STR TIME
------------------------------ -------------------
STEP BEGIN 2010-04-28 16:33:43
STEP MIDDLE 2010-04-28 16:34:43
STEP END 2010-04-28 16:35:43
這種方法適用於專門的監測程式。不過DBMS_PIPE包需要額外的授權