阅读内容 

通过缓存数据库结果提高PHP性能(2)

[日期:2006-09-14] 来源:  作者: [字体: ]
     清单 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 脚本的说明,请参阅本文后面的构建客户端 部分。
  
  将表添加到现有注册
  
    前一部分介绍了如何使用更改通知服务使数据库在注册对象(在以上示例中为 ORDERS 表)发生更改时发出通知。但从性能角度而言,客户端应用程序可能更希望缓存 ORDER_ITEMS 表而非 ORDERS 表本身的查询结果集,这是因为它在每次访问订单时,不得不从 ORDERS 表中只检索一行,但同时必须从 ORDER_ITEMS 表中检索多个行。在实际情况中,订单可能包含数十个甚至数百个订单项。
  
    由于您已经对 ORDERS 表注册了查询,因此不必再创建一个注册来注册对 ORDER_ITEMS 表的查询了。相反,您可以使用现有注册。为此,您首先需要检索现有注册的 ID。可以执行以下查询来完成此工作:
  
  SELECT regid, table_name FROM user_change_notification_regs;  结果可能如下所示:
  
  REGID TABLE_NAME
  ----- --------------
  241 OE.ORDERS
    获取注册 ID 后,可以使用 DBMS_CHANGE_NOTIFICATION.ENABLE_REG 函数将一个新对象添加到该注册,如下所示:
  
  DECLARE
  ord_id NUMBER;
  BEGIN
  DBMS_CHANGE_NOTIFICATION.ENABLE_REG(241);
  SELECT order_id INTO ord_id FROM order_items WHERE ROWNUM < 2;
  DBMS_CHANGE_NOTIFICATION.REG_END;
  END;
  /
    完成了!从现在开始,数据库将生成一个通知来响应对 ORDERS 和 ORDER_ITEMS 所做的任何更改,并调用 orders_nf_callback 过程来处理通知。因此,下一步就是编辑 orders_nf_callback,以便它可以处理因对 ORDER_ITEMS 表执行 DML 操作而生成的通知。但在重新创建 orders_nf_callback 过程之前,您需要创建以下将在更新过程中引用的表类型:
  
  CREATE TYPE rdesc_tab AS TABLE OF SYS.CHNF$_RDESC;  然后,返回清单 2,在以下代码行之后:
  
  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;
    插入以下代码:
  
  IF (tblname = 'OE.ORDER_ITEMS') THEN
  FOR rec IN (SELECT DISTINCT(o.order_id) o_id FROM
  TABLE(CAST(ntfnds.table_desc_array(i).row_desc_array AS rdesc_tab)) t,
  orders o, order_items d WHERE t.row_id = d.rowid AND d.order_id=o.order_id)
  LOOP
  sendNotification(url, tblname, rec.o_id);
  END LOOP;
  END IF;
    重新创建 orders_nf_callback 后,您需要测试它能否正常工作。为此,您可以针对 ORDER_ITEMS 表执行下列 UPDATE 语句并提交该事务:
  
  UPDATE ORDER_ITEMS SET quantity = 160 WHERE order_id=2421 AND line_item_id=1;
  UPDATE ORDER_ITEMS SET quantity = 160 WHERE order_id=2421 AND line_item_id=2;
  COMMIT;
    然后,检查 nfresults 表,如下所示:
  
  SELECT TO_CHAR(operdate, 'dd-mon-yy hh:mi:ss') operdate,
  rslt_msg FROM nfresults WHERE tblname = 'OE.ORDER_ITEMS';  输出可能如下所示:
  
  OPERDATE RSLT_MSG
  ------------------- --------------
  03-mar-06 12:32:27 Not Found
    
    做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。

阅读:
录入:blue1000

推荐 】 【 打印
相关新闻      
本文评论       全部评论
发表评论
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款


点评: 字数
姓名:
Advertisement
内容查询


Advertisement