php - 在 PDO 中使用持久连接有什么缺点

标签 php pdo

在 PDO 中,可以使用 PDO::ATTR_PERSISTENT 属性建立持久连接。根据php手册 -

Persistent connections are not closed at the end of the script, but are cached and re-used when another script requests a connection using the same credentials. The persistent connection cache allows you to avoid the overhead of establishing a new connection every time a script needs to talk to a database, resulting in a faster web application.

手册还建议在使用 PDO ODBC 驱动程序时不要使用持久连接,因为它可能会妨碍 ODBC 连接池过程。

显然,在 PDO 中使用持久连接似乎没有任何缺点,除了最后一种情况。但是,我想知道使用这种机制是否还有其他缺点,即这种机制导致性能下降或类似情况的情况。

最佳答案

请务必阅读this answer below ,其中详细介绍了缓解此处概述的问题的方法。


使用 PDO 存在与使用任何其他执行持久连接的 PHP 数据库接口(interface)相同的缺点:如果您的脚本在数据库操作的中间意外终止,则获得剩余连接的下一个请求将在死脚本离开的地方拾取离开。连接在进程管理器级别保持打开状态(Apache for mod_php,如果您使用 FastCGI,则为当前的 FastCGI 进程等),而不是在 PHP 级别,并且 PHP 不会告诉父进程让连接在何时终止脚本异常终止。

如果死脚本锁定了表,这些表将保持锁定状态,直到连接断开或获取连接的下一个脚本解锁表本身。

如果死脚本处于事务的中间,则可能会阻塞大量表,直到死锁计时器启动,即使这样,死锁计时器也可以杀死新请求而不是导致问题的旧请求.

如果死脚本处于事务中间,则获取该连接的下一个脚本也会获取事务状态。很有可能(取决于您的应用程序设计)下一个脚本实际上可能不会尝试提交现有事务,或者在不应该提交的时候提交,或者在不应该提交的时候回滚。

这只是冰山一角。通过在每个脚本请求的脏连接后始终尝试清理,这一切都可以在一定程度上得到缓解,但这可能会很痛苦,具体取决于数据库。除非您已将创建数据库连接确定为脚本中的瓶颈(这意味着您已经使用 xdebug 和/或 xhprof 完成了代码分析),您应该将持久连接视为解决任何问题的方法。

此外,大多数现代数据库(包括 PostgreSQL)都有自己首选的连接池执行方式,它们没有普通的基于 PHP 的持久连接所具有的直接缺点。


为了澄清一点,我们在我的工作场所使用持久连接,但不是自愿的。我们遇到了奇怪的连接行为,从我们的应用服务器到我们的数据库服务器的初始连接花费了正好三秒钟,而它本应该花费几分之一的时间。一秒。我们认为这是一个内核错误。我们放弃了尝试解决它,因为它是随机发生的,无法按需复制,而且我们外包的 IT 没有具体的能力来追踪它。

不管怎样,当仓库里的人正在处理几百个进来的零件时,每个零件需要三秒半而不是半秒,我们必须在他们绑架我们所有人并让我们帮助他们之前采取行动.因此,我们在我们自己开发的 ERP/CRM/CMS 怪物中进行了一些尝试,并亲 body 验了持久连接的所有恐怖。我们花了 几周 来追查看似随机发生的所有细微的小问题和奇怪的行为。事实证明,我们的用户努力从我们的应用程序中挤出的那些每周一次的 fatal error 是留下锁定的表、放弃的交易和其他不幸的不稳定状态。

这个令人唏嘘的故事有一个道理:它破坏了我们从未想过会破坏的东西,全都是以性能的名义。这种权衡是不值得的,我们急切地等待有一天我们可以切换回正常连接,而不会引起用户的骚乱。

关于php - 在 PDO 中使用持久连接有什么缺点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3332074/

相关文章:

php - Pdo 行计数错误

mysql join 两个表选择和记录问题

PHP - MYSQL 从 while 循环中过滤包含任何指定单词的变量

pdo - Zend PDO ODBC 数据库选择

PHP为网页中的变量设置变量

php - MySql Select语句问题

java - 如何找到正确的用户名和密码标签?

php - 为什么我不禁用 PDO::MYSQL_ATTR_DIRECT_QUERY?

php - 通过单个查询获取类别和文章

php - 使用 joomla 以编程方式注销