请务必阅读下面的答案,其中详细介绍了缓解此处概述的问题的方法。
使用PDO存在与执行持久连接的任何其他PHP数据库接口相同的缺点:如果您的脚本在数据库操作过程中意外终止,则获得剩余连接的下一个请求将从死脚本中断的位置继续。连接在进程管理器级别保持打开状态(Apache表示mod_php,如果您使用的是FastCGI,则为当前的FastCGI进程等),而不是PHP级别,并且PHP不会告诉父进程在脚本异常终止时让连接死亡。
如果失效脚本锁定了表,则这些表将保持锁定状态,直到连接终止或获取连接的下一个脚本解锁表本身。
如果死脚本处于事务的中间,则可能会阻塞大量表,直到死锁计时器启动,即使这样,死锁计时器也可以杀死较新的请求,而不是导致问题的旧请求。
如果死脚本位于事务的中间,则获取该连接的下一个脚本也会获取事务状态。很有可能(取决于您的应用程序设计)下一个脚本实际上可能从未尝试提交现有事务,或者在不应该提交时提交,或者在不应该提交时回滚。
这只是冰山一角。通过在每个脚本请求的脏连接之后始终尝试清理,可以在一定程度上缓解这一切,但根据数据库的不同,这可能是一种痛苦。除非您已将创建数据库连接确定为脚本中的瓶颈(这意味着您已使用 xdebug 和/或 xhprof 进行了代码分析),否则不应将持久连接视为任何操作的解决方案。
此外,大多数现代数据库(包括PostgreSQL)都有自己喜欢的执行连接池的方式,这些方式没有基于普通PHP的持久连接那样的直接缺点。
为了澄清一点,我们在我的工作场所使用持久的联系,但不是自愿的。我们遇到了奇怪的连接行为,从我们的应用程序服务器到数据库服务器的初始连接正好需要三秒钟,而它应该只需要几分之一秒。我们认为这是一个内核错误。我们放弃了尝试对它进行故障排除,因为它是随机发生的,无法按需复制,而且我们的外包IT没有具体的能力来跟踪它。
无论如何,当仓库里的人正在处理几百个进货零件时,每个零件需要三秒半而不是半秒,我们不得不在他们绑架我们所有人并让我们帮助他们之前采取行动。因此,我们在我们本土的ERP / CRM / CMS怪物中翻转了一些东西,并亲身体验了持久连接的所有恐怖。我们花了数周时间才追踪到所有看似随机发生的微妙小问题和奇怪的行为。事实证明,我们的用户每周一次的致命错误会从我们的应用程序中挤出来,这些错误会留下锁定的表格,废弃的交易和其他不幸的不稳定状态。
这个可泣的故事有一个观点:它打破了我们从未预料到会打破的东西,所有这些都是以表演的名义。这种权衡是不值得的,我们急切地等待着有一天我们可以切换回正常连接,而不会受到用户的骚乱。