PHP 8.2.20发布!

持久数据库连接

持久连接是指当脚本的执行结束。当永久连接请求时,PHP检查是否已经存在相同的持久性连接(从早期开始一直保持打开状态)-如果存在使用它。如果它不存在,则创建链接。“相同”connection是打开到同一主机的连接相同的用户名和密码(如果适用)。

不完全熟悉web服务器工作方式的人并且分配负载可能会将持久连接错误地理解为他们不是。尤其是,他们做到了如果您能够在同一链接上打开“用户会话”让你有能力建立交易效率高,而且他们不会做很多其他事情东西。事实上,要非常清楚这个主题,持久的连接不会给你任何非持久性无法实现的功能兄弟。

为什么?

这与网络服务器的工作方式有关其中您的web服务器可以利用PHP生成网页。

第一种方法是使用PHP作为CGI“包装器”。当运行此方法是创建并销毁PHP解释器的实例对于web服务器的每个页面请求(对于PHP页面)。因为它在每次请求后都会被销毁获取(例如到SQL数据库服务器的链接)在以下情况下关闭它被摧毁了。在这种情况下,你不会从尝试中获得任何好处使用持久连接——它们根本不持久。

第二种也是最流行的方法是将PHP作为模块运行在多进程web服务器,目前仅包括Apache。A类多进程服务器通常有一个进程(父进程)协调一组实际执行提供网页的工作。当请求来自客户,它被交给一个还没有交的孩子为另一个客户服务。这意味着当同一客户对服务器的第二个请求,可以由另一个子进程比第一次。打开持久连接时,下面每个请求SQL服务的页面都可以重用相同的已建立与SQL server的连接。

最后一种方法是使用PHP作为多线程web的插件服务器。目前PHP支持WSAPI和NSAPI(onWindows),所有这些都允许将PHP用作多线程上的插件Netscape FastTrack(iPlanet)、Microsoft Internet Information等服务器服务器(IIS)和O'Reilly的网站专业版。行为本质上是与前面描述的多进程模型相同。

如果持久连接没有任何添加的功能它们有好处吗?

这里的答案非常简单——效率。持久如果创建到SQL的链接的开销很大,那么连接就很好服务器高。这项开销是否真的很高取决于在许多因素上。比如,它是什么样的数据库,是否它位于您的web服务器所在的同一台计算机上加载了SQL服务器所在的机器等等。这个底线是,如果该连接开销很高,那么将持续存在联系对你有很大帮助。它们导致子进程只需在其整个生命周期内连接一次,而不是每次它处理需要连接到SQL的页面的时间服务器。这意味着,对于每个打开持久性连接将具有自己的到服务器。例如,如果您有20个不同的子进程运行与SQL server建立持久连接的脚本,您将有20个不同的SQL server连接,其中一个来自每个孩子。

但是请注意,如果您使用数据库的连接限制超过了持久性子连接。如果数据库的并发限制为16连接,在繁忙的服务器会话过程中,17个子节点线程尝试连接,则无法连接。如果存在脚本中不允许关闭连接的错误关闭(例如无限循环),数据库只有16个连接可能会很快被淹没。检查数据库文档以了解有关处理废弃或空闲连接的信息。

警告

在以下情况下,需要记住几个额外的注意事项使用持久连接。一是使用表格时锁定持久连接,如果脚本用于reason无法释放锁,然后使用相同的连接将无限期阻塞,并且可能需要重新启动httpd服务器或数据库服务器。另一个是当使用事务时,事务块还将转到使用该连接的下一个脚本if脚本执行在事务块结束之前结束。无论哪种情况,您都可以使用寄存器关闭函数()注册简单的清理功能可以解锁表或回滚交易。更好的是,通过不使用使用表锁或事务(您仍然可以在其他地方使用它们)。

重要的总结。持久连接设计为具有到常规连接的一对一映射。这意味着你应该总是能够替换持久性具有非持久连接的连接,并且不会更改脚本的行为方式。可以(和可能会)更改脚本的效率,但不会行为!

另请参见ibase_pconnect(),ociplogon(),odbc_pconnect(),oci_pconnect(),pfsockopen()、和pg_pconnect().

添加注释

用户贡献的笔记12条注释

汤姆
14年前
PHP有第三种情况:在fastCGI接口上运行。在这种情况下,PHP进程不会在每次请求后被销毁,因此持久连接会持续存在。设置PHP_FCGI_CHILDREN<<mysql的max_connections,就可以了。
alfadog点网的php
10年前
另外一个与odbc_pconnect和可能的其他pconnect变体无关的选项:

如果连接遇到错误(错误的SQL、不正确的请求等),对于该连接上的每个后续操作,该错误都将返回,并显示在odbc_errormsg中,即使后续操作不会导致另一个错误。

例如:

脚本与odbc_pconnect连接。
连接是在首次使用时创建的。
该脚本调用查询“Select*FROM Table1”。
表1不存在,odbc_errormsg包含该错误。

稍后(也许几天),会使用odbc_pconnect的相同参数调用不同的脚本。
连接已存在,对其进行了重用。
该脚本调用一个查询“Select*FROM Table0”。
查询运行良好,但odbc_errormsg仍返回关于Table1不存在的错误。

我没有找到使用odbc_函数清除该错误的方法,所以请注意这个问题,或者使用odbc_connect。
加拿大lakeheadu的ynzhang
15年前
使用pg_pconnect()似乎无法持久化临时视图/表。因此,如果您试图使用查询结果创建临时视图/表,然后使用同一会话的下一个脚本访问它们,那么您就不太走运了。在每个PHP脚本结束后,这些临时视图/表都会消失。解决这个问题的一种方法是创建真实的视图/表,将会话ID作为名称的一部分,并将名称和创建时间记录在一个公共表中。有一个垃圾收集脚本来删除会话已过期的视图/表。
ambrish在php点网
13年前
在IBM_DB2扩展v1.9.0或更高版本中,在请求结束时对持久连接执行事务回滚,从而结束事务。如果脚本执行在事务块之前结束,这将防止事务块转移到使用该连接的下一个请求。
gmail dot com的pacerier
8年前
还有人注意到最后一段与上面的内容相矛盾吗?

(缓存页面:https://archive.is/ZAOwy网站)
甲骨文网络公司的克里斯托弗·道琼斯
16年前
对于oci8扩展,“如果脚本执行在事务块之前结束,那么在使用事务时,事务块也会转移到使用该连接的下一个脚本”是不正确的。oci8扩展使用持久连接在结束脚本处执行回滚,从而结束事务。回滚也会释放锁。然而,持久连接上的任何ALTER SESSION命令(例如更改日期格式)都将保留到下一个脚本。
安迪在paradigm-reborned.com
17年前
对于那些使用MySQL并发现大量剩余休眠进程的用户,请查看MySQL的wait_timeout指令。默认设置为8小时,但几乎所有优秀的生产服务器都会降低到60秒的范围。即使在我的测试服务器上,我也遇到了来自剩余持久连接的太多连接的问题。
jean_christian在myrealbox网站
21年前
如果有人想知道为什么即使使用持久连接,空闲数据库进程(开放连接)的数量似乎也在增长,原因如下:

“您可能正在使用Apache等多进程web服务器。因为
数据库连接不能在不同的进程之间共享
如果请求碰巧到达另一个web服务器,则创建一个
子进程。"
在GMail dot com聚会
18年前
如果在同一服务器上有多个数据库,并且正在使用持久连接,则必须在所有表名前面加上特定的数据库名称。

使用xxx_select_db函数更改数据库会更改所有共享该连接的用户的连接数据库(假设PHP运行的是共享的,而不是CGI/CLI)。

如果您有两个数据库(实时数据库和存档数据库),并且您的脚本同时与这两个数据库进行通信,则不能使用两个持久连接并为每个连接更改数据库。

在内部,即使您没有指定要使用持久连接,也会使用持久连接。这就是为什么new_link被添加到mysql_connect/mssql_connect(PHPV4.2.0+)中的原因。
法比奥
18年前
实际上,您可以为连接提供一个端口http://de2.php.net/manual/en/function.mysql-pconnect.php#AEN101879

只需使用“hostname:port”作为服务器地址。
whatspaz at g NO dot垃圾邮件dot抄送
17年前
作为对尼克网站的回应,你有没有尝试过刷新特权。这应该会重新加载这些权限。
aaryal在foresightint网站
20年前
这是我的“你知道什么”中的一部分。如果您在同一台主机上运行多个数据库服务器(例如,在多个端口上运行MySQL),则无法使用pconnect,因为端口号不是数据库连接键的一部分。尤其是如果您有相同的用户名和密码来连接到运行在不同端口上的所有数据库服务器。但它可能是特定于php-MySQL的。您可能会得到一个与您要求的端口完全不同的连接。
到顶部