dedecms织梦内容管理系统    
首页 | java | C/C++ | PHP | 操作系统 | ajax | 脚本编程 | 安全技术 | 本站下载页 | flex | CRM | 专题 | QQ群 | 测试中心 | 会员中心 | 积分规则
  当前位置:主页>PHP>php技术资料>文章内容
通过缓存数据库结果提高PHP性能
来源:Oracle中国     作者:    
  众所周知,缓存查询的结果可以显著缩短脚本执行时间,并最大限度地减少数据库服务器上的负载。如果要处理的数据基本上是静态的,则该技术将非常有效。这是因为对远程数据库的许多数据请求最终可以从本地缓存得到满足,从而不必连接到、执行查询以及获取结果。

  但当您使用的数据库与 Web 服务器位于不同的计算机上时,缓存数据库结果集通常是一个不错的方法。不过,根据您的情况确定最佳的缓存策略却是一个难题。例如,对于使用最新数据库结果集比较重要的应用程序而言,时间触发的缓存方法(缓存系统常用的方法,它假设每次到达失效时间戳记时就重新生成缓存)可能并不是一个令人满意的解决方案。这种情况下,您需要采用一种机制,每当应用程序需要缓存的数据库数据发生更改时,该机制将通知该应用程序,以便该应用程序将缓存的过期数据与数据库保持一致。这种情况下使用“更改通知”(一个新的 10g 第 2 版特性)将非常方便。

  “更改通知”入门

  “更改通知”特性的用法非常简单:创建一个针对通知执行的通知处理程序 – 一个 PL/SQL 或客户端 OCI 回调。然后,针对要接收其更改通知的对象注册一个查询,以便每当事务更改其中的任何对象并提交时调用通知处理程序。通常情况下,通知处理程序将被修改的表的名称、所做更改的类型以及所更改行的行 ID(可选)发送给客户端监听程序,以便客户端应用程序可以在响应中执行相应的处理。

  为了了解“更改通知”特性的作用方式,请考虑以下示例。假设您的 应用程序访问 OE.ORDERS 表中存储的订单以及 OE.ORDER_ITEMS 中存储的订单项。鉴于很少更改已下订单的信息,您可能希望应用程序同时缓存针对 ORDERS 和 ORDER_ITEMS 表的查询结果集。要避免访问过期数据,您可以使用“更改通知”,它可让您的应用程序方便地获知以上两个表中所存储数据的更改。

  您必须先将 CHANGE NOTIFICATION 系统权限以及 EXECUTE ON DBMS_CHANGENOTIFICATION 权限授予 OE 用户,才能注册对 ORDERS 和 ORDER_ITEMS 表的查询,以便接收通知和响应对这两个表所做的 DML 或 DDL 更改。为此,可以从 SQL 命令行工具(如 SQL*Plus)中执行下列命令。
CONNECT / AS SYSDBA; 

GRANT CHANGE NOTIFICATION TO oe; 

GRANT EXECUTE ON DBMS_CHANGE_NOTIFICATION TO oe; 


  确保将 init.ora 参数 job_queue_processes 设置为非零值,以便接收 PL/SQL 通知。或者,您也可以使用下面的 ALTER SYSTEM 命令:
ALTER SYSTEM SET "job_queue_processes"=2;
  然后,在以 OE/OE 连接后,您可以创建一个通知处理程序。但首先,您必须创建将由通知处理程序使用的数据库对象。例如,您可能需要创建一个或多个表,以便通知处理程序将注册表的更改记录到其中。在以下示例中,您将创建 nfresults 表来记录以下信息:更改发生的日期和时间、被修改的表的名称以及一个消息(说明通知处理程序是否成功地将通知消息发送给客户端)。
CONNECT oe/oe; 



CREATE TABLE nfresults ( 

operdate DATE,  

tblname VARCHAR2(60),  

rslt_msg VARCHAR2(100) 

); 

  在实际情况中,您可能需要创建更多表来记录通知以及所更改行的行 ID 等信息,但就本文而言,nfresults 表完全可以满足需要。

  使用 UTL_HTTP 向客户端发送通知

  您可能还要创建一个或多个 PL/SQL 存储过程,并从通知处理程序中调用这些存储过程,从而实现一个更具可维护性和灵活性的解决方案。例如,您可能要创建一个实现将通知消息发送给客户端的。“清单 1”是 PL/SQL 过程 sendNotification。该过程使用 UTL_HTTPPL 程序包向客户端应用程序发送更改通知。

  清单 1. 使用 UTL_HTTP 向客户端发送通知
CREATE OR REPLACE PROCEDURE sendNotification(url IN VARCHAR2,  

tblname IN VARCHAR2, order_id IN VARCHAR2) IS 

req   UTL_HTTP.REQ; 

resp  UTL_HTTP.RESP; 

err_msg VARCHAR2(100); 

tbl VARCHAR(60); 

BEGIN 

tbl:=SUBSTR(tblname, INSTR(tblname, '.', 1, 1)+1, 60); 

BEGIN 

req := UTL_HTTP.BEGIN_REQUEST(url||order_id||'&'||'table='||tbl); 

resp := UTL_HTTP.GET_RESPONSE(req); 

INSERT INTO nfresults VALUES(SYSDATE, tblname, resp.reason_phrase); 

UTL_HTTP.END_RESPONSE(resp); 

EXCEPTION WHEN OTHERS THEN 

err_msg := SUBSTR(SQLERRM, 1, 100); 

INSERT INTO nfresults VALUES(SYSDATE, tblname, err_msg); 

END; 

COMMIT; 

END; 

/ 


  如“清单 1”所示,sendNotification 以 UTL_HTTP.BEGIN_REQUEST 发出的 HTTP 请求的形式向客户端发送通知消息。此 URL 包含 ORDERS 表中已更改行的 order_id。然后,它使用 UTL_HTTP.GET_RESPONSE 获取客户端发出的响应信息。实际上,sendNotification 并不需要处理客户端返回的整个响应,而是只获取一个在 RESP 记录的 reason_phrase 字段中存储的简短消息(描述状态代码)。

  创建通知处理程序

  现在,您可以创建一个通知处理程序,它将借助于上面介绍的 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.?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 表中被修改的行发出的通知。

[1]    

 

 

上一篇:大型系统上PHP令人不爽的九大原因   下一篇:PHP5 OOP编程中的代理与异常定制
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
用户名: 新注册) 密码: 匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论
  热点文章
·通过对PHP服务器端特性的配置加
·php与mysql三日通
·AJAX技术在PHP开发中的简单应用
·大家所使用的PHP开发环境
·PHP缓存的实现
·针对PHP新手总结的PHP基础知识
·一个简单实现多条件查询的例子
·PHP串行化变量和序列化对象
·PHP表单
·推荐阅读:php技术生成静态页面
·php实用函数
·php生成随机数
  相关文章
·大型系统上PHP令人不爽的九大原
·PHP5 OOP编程中的代理与异常定制
·PHP5 OOP编程之代理与定制异常
·PHP新手总结的PHP基础知识
·利用PHP的OOP特性实现数据保护
·PHP下一代的五个framework介绍
·基于PHP和AJAX创建RSS聚合器
·PHP+MySQL应用中使用XOR运算加密
·WAP与PHP程序设计之基础篇
·PHP中使用crypt()实现用户身份验
·PHPUnit袖珍指南之命令行测试工
·使用PHP和AJAX的XML编程
  相关信息
copy right @ 百家拳软件项目研究室 2007 辽ICP备07011763