通過緩存數據庫結果提高PHP性能(2)

日期:2006-09-28  作者:喜騰小二  來源:PHPChina


創建通知處理程序

  現在,您可以創建一個通知處理程序,它將藉助於上麵介紹的 sendNotification
過程嚮客戶端發送更改通知。來看一看“清單 2”中的 PL/SQL 過程 orders_nf_callback。

  清單 2.
處理對 OE.ORDERS 表所做更改的通知的通知處理程序

CREATE OR REPLACE PROCEDURE orders_nf_callback (ntfnds IN SYS.CHNF$_DESC) IS
tblname VARCHAR2(60);
numtables NUMBER;
event_type NUMBER;
row_id VARCHAR2(20);
numrows NUMBER;
ord_id VARCHAR2(12);
url VARCHAR2(256) := 'http://webserverhost/phpcache/dropResults.php?order_no=';
BEGIN
event_type := ntfnds.event_type;
numtables := ntfnds.numtables;
IF (event_type = DBMS_CHANGE_NOTIFICATION.EVENT_OBJCHANGE) THEN
FOR i IN 1..numtables LOOP
tblname := ntfnds.table_desc_array(i).table_name;
IF (bitand(ntfnds.table_desc_array(i).opflags,
DBMS_CHANGE_NOTIFICATION.ALL_ROWS) = 0) THEN
numrows := ntfnds.table_desc_array(i).numrows;
ELSE
numrows :=0;
END IF;
IF (tblname = 'OE.ORDERS') THEN
FOR j IN 1..numrows LOOP
row_id := ntfnds.table_desc_array(i).row_desc_array(j).row_id;
SELECT order_id INTO ord_id FROM orders WHERE rowid = row_id;
sendNotification(url, tblname, ord_id);
END LOOP;
END IF;
END LOOP;
END IF;
COMMIT;
END;
/
  如“清單 2”所示,此通知處理程序將 SYS.CHNF$_DESC
對象用作參數,然後使用它的屬性獲取該更改的詳細信息。在該示例中,此通知處理程序將隻處理數據庫為響應對注冊對象進行的 DML 或 DDL
更改(也就是說,僅當通知類型為 EVENT_OBJCHANGE
時)而發佈的通知,並忽略有關其他數據庫事件(如實例啓動或實例關閉)的通知。從以上版本開始,處理程序可以處理針對 OE.ORDERS
表中每個受影響的行發出的更改通知。在本文後麵的“將表添加到現有注冊”部分中,您將嚮處理程序中添加幾行代碼,以便它可以處理針對 OE.ORDER_ITEMS
表中被修改的行發出的通知。

  為更改通知創建注冊

  創建通知處理程序後,必須為其創建一個查詢注冊。對於本示例而言,您必須在注冊過程中對 OE.ORDER 表執行查詢並將
orders_nf_callback 指定為通知處理程序。您還需要在 DBMS_CHANGE_NOTIFICATION 程序包中指定 QOS_ROWIDS
選項,以便在通知消息中啓用 ROWID 級別的粒度。“清單 3”是一個 PL/SQL 塊,它為 orders_nf_callback 通知處理程序創建查詢注冊。


  清單 3. 為通知處理程序創建查詢注冊
DECLARE
REGDS SYS.CHNF$_REG_INFO;
regid NUMBER;
ord_id NUMBER;
qosflags NUMBER;
BEGIN
qosflags := DBMS_CHANGE_NOTIFICATION.QOS_RELIABLE +
DBMS_CHANGE_NOTIFICATION.QOS_ROWIDS;
REGDS := SYS.CHNF$_REG_INFO ('orders_nf_callback', qosflags, 0,0,0);
regid := DBMS_CHANGE_NOTIFICATION.NEW_REG_START (REGDS);
SELECT order_id INTO ord_id FROM orders WHERE ROWNUM<2;
DBMS_CHANGE_NOTIFICATION.REG_END;
END;
/
  本示例針對 ORDERS 表創建了一個注冊,並將 orders_nf_callback 用作通知處理程序。現在,如果您使用 DML 或 DDL
語句修改 ORDERS 表並提交事務,則將自動調用 orders_nf_callback 函數。例如,您可能針對 ORDERS 表執行下列 UPDATE
語句並提交該事務:
UPDATE ORDERS SET order_mode = 'direct' WHERE order_id=2421;
UPDATE ORDERS SET order_mode = 'direct' WHERE order_id=2422;
COMMIT;
  要確保數據庫發佈了通知來響應以上事務,您可以檢查 nfresults 表:
SELECT TO_CHAR(operdate, 'dd-mon-yy hh:mi:ss') operdate,
tblname, rslt_msg FROM nfresults;
  結果應如下所示:
OPERDATE TBLNAME RSLT_MSG
--------------------- ----------- ---------
02-mar-06 04:31:28 OE.ORDERS Not Found
02-mar-06 04:31:29 OE.ORDERS Not Found
  從以上結果中可以清楚地看到,orders_nf_callback
已經正常工作,但未找到客戶端腳本。在該示例中出現這種情況並不意外,這是因為您並未創建 URL 中指定的 dropResults.php 腳本。有關
dropResults.php 腳本的說明,請參閱本文後麵的構建客戶端部分。

<<<返回技術中心

技術文章

站內新聞

我要啦免费统计