7

我已经阅读了大量关于 PHP 和 MySQL 之间持久性数据库连接的文章(mysql_connect 与 mysql_pconnect)。与 PDO 和 MySQLi 相同。这绝对是我对这一点缺乏了解,但是如何在网页之间保持数据库连接?在这段代码中:

$conn = mysql_pconnect( $server , $user, $pass );
mysql_select_db( $dbname );

如果两个用户同时加载这个页面,使用两个不同的 $dbname 变量,PHP 会只建立一个或两个数据库连接吗?我相当肯定

$conn = mysql_connect( $server , $user, $pass );

将建立两个连接。

如果 pconnect 重用第一个用户打开的连接,mysql_select_db 调用是否对第二个用户有效?

理想情况下,我正在寻找一种减少数据库连接但仍然能够在每个 PHP 脚本中设置默认数据库的方法。我有客户都使用相同的 PHP 脚本,但数据存储在他们自己的客户端数据库中(因此,$dbname 总是不同的,但 MySQL 连接参数是相同的 - 相同的 mysql ip 地址、用户和密码)。

希望这是有道理的。我们可以使用 MySQL、MySQLi 或 PDO,只需要知道如何以最佳方式完成此操作,而不会让客户端意外将数据写入其他人的数据库!提前致谢。

4

2 回答 2

7

持久性由嵌入在网络服务器中的 PHP 副本完成。通常你是对的——如果 PHP 在 CGI 模式下运行,就不可能有持久连接,因为当请求完成并且 PHP 关闭时,没有任何东西可以持久存在。

但是,由于网络服务器中嵌入了 PHP 的副本,并且网络服务器本身在请求之间保持运行,因此可以在该“永久”PHP 中维护一个持久连接池。

但是,请注意,在 Apache 多工作器类型的服务器模型上,连接池是按孩子维护的。如果将池限制设置为 10,则每个 Apache 子节点将有 10 个连接。20 个孩子 = 200 个连接。

持久连接还会导致死锁和其他难以调试的问题的长期问题。请记住 - 不能保证用户的 HTTP 请求将由 SAME apache child/mysql 连接提供服务。如果脚本在数据库事务的中途终止,该事务将不会回滚,因为 MySQL 看不到 HTTP 方面的内容 - 它所看到的只是 mysql<->apache 连接仍然打开并假设一切正常.

下一个点击特定 apache/mysql 子/连接组合的用户现在将神奇地结束在该事务的中间,不知道该事务已打开。基本上,它相当于一个未冲水马桶的网络——之前用户的所有“垃圾”仍然存在。

使用非持久连接,每次连接时都可以保证拥有一个“干净”的环境。

于 2012-08-01T17:10:08.403 回答
6

通过阅读文档和评论,我看到:

mysql_pconnect 上的文档(不推荐使用的方法)

其次,脚本执行结束时不会关闭与 SQL 服务器的连接。相反,该链接将保持打开以供将来使用(mysql_close() 不会关闭由 mysql_pconnect() 建立的链接)。

以及对该页面的评论

持久连接适用于由 fastCGI 管理的 CGI PHP,与上面的建议相反,它们仅适用于模块版本。那是因为 fastCGI 让 PHP 进程在请求之间运行。这种模式下的持久连接也很容易不受连接限制的影响,因为您可以设置 PHP_FCGI_CHILDREN << mysql's max_connections <<< Apache's MaxClients。这也节省了资源。

mysqli_connect 上的文档(新方法)

p 前置主机:打开一个持久连接。mysqli_change_user() 在从连接池打开的连接上自动调用。

mysqli_change_user 的文档:

更改指定数据库连接的用户并设置当前数据库。

所以我的理解如下: pconnect 在脚本结束后保持连接打开,但是当一个进程(或者可能是一组进程)仍然存在时(比如在设置了 FCGI 的服务器中)。一次只有一个脚本使用连接,当一个新脚本获取该连接时,用户和数据库都会更新。

因此,如果您使用 FCGI 和持久连接,您可以减少打开的数据库连接的数量,但同时运行的脚本不会共享同一个连接。连接被混淆选择哪个数据库没有问题。

于 2012-08-01T17:03:28.700 回答