OCI8 扩展提供了三种不同的函数用于连接到 Oracle。标准连接函数是 oci_connect()。这将创建一个与 Oracle 数据库的连接,并返回后续数据库调用使用的资源。
连接到 Oracle 服务器在完成所需的时间方面是一个相当昂贵的操作。 oci_pconnect() 函数使用持久连接缓存,这些连接可以在不同的脚本请求之间重复使用。这意味着连接开销通常只会在每个 PHP 进程(或 Apache 子进程)中发生一次。
如果应用程序使用不同的数据库凭据集为每个 Web 用户连接到 Oracle,则 oci_pconnect() 使用的持久缓存随着并发用户数量的增加将变得不太有用,以至于它可能开始由于维护太多空闲连接而对 Oracle 服务器的整体性能产生不利影响。如果应用程序以这种方式构建,建议使用 oci8.max_persistent 和 oci8.persistent_timeout 配置设置来调整应用程序(这些将控制持久连接缓存大小和生存期)、使用 Oracle 数据库驻留连接池(在 Oracle 数据库 11g 或更高版本中),或使用 oci_connect() 代替。
oci_connect() 和 oci_pconnect() 都使用连接缓存;如果在给定脚本中对 oci_connect() 的多次调用使用相同的参数,则第二个和后续调用将返回现有的连接句柄。 oci_connect() 使用的缓存将在脚本运行结束时清理,或者在显式关闭连接句柄时清理。 oci_pconnect() 函数的行为类似,尽管其缓存是单独维护的,并且在 HTTP 请求之间持续存在。
此缓存功能意味着这两个句柄不是事务隔离的(实际上它们是同一个连接句柄,因此没有任何隔离)。如果应用程序需要两个独立的、事务隔离的连接,则使用 oci_new_connect()。
oci_pconnect() 缓存会在 PHP 进程终止时清除,并且任何数据库连接也会关闭,因此持久连接的有效使用要求 PHP 成为 Apache 模块或与 FPM 或类似模块一起使用。当 PHP 与 CGI 一起使用或通过命令行使用时,持久连接将不会比 oci_connect() 有任何优势。
oci_new_connect() 函数始终创建一个与 Oracle 服务器的新连接,而不管可能已经存在哪些其他连接。高流量 Web 应用程序应避免使用 oci_new_connect(),特别是在应用程序的最繁忙部分。
持久连接可以由用户关闭,从而允许对连接资源使用进行更细粒度的控制。现在,当没有 PHP 变量引用它们时,持久连接也会自动关闭,例如在 PHP 用户函数的作用域结束时。这将回滚任何未提交的事务。对持久连接的这些更改使它们的行为类似于非持久连接,简化了接口,允许更大的应用程序一致性和可预测性。使用 oci8.old_oci_close_semantics 设置为 On 以保留历史行为。
在 Apache 或 FPM 进程重新生成后自动重新建立 PHP 持久连接意味着 Oracle 数据库 LOGON
触发器仅推荐用于设置会话属性,而不是用于每个应用程序的用户连接请求。
PHP 支持 Oracle 数据库驻留连接池 (DRCP)。DRCP 允许更有效地使用数据库机器内存并提供高可扩展性。使用 DRCP 无需或只需少量应用程序更改。
DRCP 适用于使用少量数据库模式并保持数据库连接打开很短时间的应用程序。其他应用程序应使用 Oracle 的默认 Dedicated
数据库服务器进程,或使用 Shared
服务器。
DRCP 有利于所有三种连接函数,但在使用 oci_pconnect() 创建连接时,DRCP 的可扩展性最高。
要在 OCI8 中使用 DRCP,PHP 使用的 Oracle 客户端库和 Oracle 数据库版本都必须为 11g 或更高版本。
有关 DRCP 的文档可以在多个 Oracle 手册中找到。例如,请参阅 Oracle 文档中的 » 配置数据库驻留连接池,了解使用信息。 » DRCP 白皮书 包含有关 DRCP 的背景信息。
要使用 DRCP,请安装 OCI8 扩展和 Oracle 11g(或更高版本)库,然后按照以下步骤操作
作为具有特权的数据库管理员,使用 SQL*Plus 等程序在数据库中启动连接池
SQL> execute dbms_connection_pool.start_pool;
可选地使用 dbms_connection_pool.alter_param()
配置 DRCP 设置。当前池设置可以从 DBA_CPOOL_INFO
视图中查询。
更新使用的连接字符串。对于当前使用网络连接名称(例如 MYDB
)进行连接的 PHP 应用程序
$c = oci_pconnect("myuser", "mypassword", "MYDB");
修改 tnsnames.ora 文件并添加 (SERVER=POOLED)
子句,例如
MYDB = (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp) (HOST=myhost.dom.com) (PORT=1521))(CONNECT_DATA=(SERVICE_NAME=sales) (SERVER=POOLED)))
或者,修改 PHP 中的 Easy Connect 语法并在服务名称后添加 :POOLED
$c = oci_pconnect("myuser", "mypassword", "myhost.dom.com:1521/sales:POOLED");
编辑 php.ini 并选择一个连接类名称。此名称指示连接池的逻辑划分,可用于隔离对独立应用程序的池化。具有相同用户名和连接类值的任何 PHP 应用程序都将能够共享池中的连接,从而提供更高的可扩展性。
oci8.connection_class = "MY_APPLICATION_NAME"
运行应用程序,连接到 11g(或更高版本)数据库。
注意:
使用 Oracle 客户端库 10g 的应用程序需要持久连接的性能,可以通过使用 Oracle
Shared
服务器(以前称为多线程服务器)来减少所需的数据库服务器内存量。有关信息,请参考 Oracle 文档。
注意:
通过 DRCP 连接更改密码将失败,并出现错误 ORA-56609: Usage not supported with DRCP。这是 Oracle 数据库 11g 的一项已记录的限制。