首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >充分理解PDO ATTR_PERSISTENT

充分理解PDO ATTR_PERSISTENT
EN

Stack Overflow用户
提问于 2014-05-02 16:35:23
回答 4查看 35.4K关注 0票数 28

问题:

当使用PDO时,持久连接管理背后的规则/逻辑是什么?

环境:

网络服务器

  • Windows 7 x64
  • 双核,内存为16 RAM
  • Apache 2.2.17
  • PHP 5.3.5
  • 通过DSN字符串与IP地址、端口、服务名称等进行连接。
  • DB conn没有ODBC (已经尝试创建了2个小时,谢谢Oracle!)

DB Server

  • Linux上的Oracle 10g
  • 多核4GB内存
  • 专门为我的web应用程序创建的用户名(是的,它是假的)
    • 用户:润湿器

我的理解/意见:

非持久连接

代码语言:javascript
复制
<?php

// Open a new connection
// Session created in Oracle
$dbh = new PDO('DSN', 'webuser', 'password');

// webuser is active in v$session with a SID=1

$dbh = NULL;

// webuser removed from v$session

// Manually calling $dbh = NULL; will remove the session from v$session
// OR
// Wait for script EOL so a kill-session command is sent to Oracle?

?>
  • 脚本可靠地花费了大约.09秒的时间来执行框架开销,等等.

持久连接

代码语言:javascript
复制
<?php

// Open a new connection and make it persistent
// Session created in Oracle
// Is Apache maintaining some sort of keep-alive with Oracle here?
// because I thought php.exe is only alive for the duration of the script
$dbh = new PDO('DSN', 'webuser', 'password', array(PDO::ATTR_PERSISTENT => TRUE));

// webuser is active in v$session with a SID=1

$dbh = NULL;

// webuser is still active in v$session with a SID=1

$dbh = new PDO('DSN', 'webuser', 'password', array(PDO::ATTR_PERSISTENT => TRUE));

// webuser is still active in v$session with a SID=1

// Manually calling $dbh = NULL; does not kill session
// OR
// Script EOL does not kill session
// ^^ this is good, just as expected

?>
  • 脚本在第一次访问时要花费.12秒执行,包括框架开销,等等.
  • 子序列执行采取~.04

这一问题:

我访问这个页面,webuser得到一个SID=1

我的同事访问该页面,webuser为访问此页面的新计算机获得一个额外的SID=2 <- rinse、重复和增量SID。

一个新的访问者不应该重用SID=1吗?

欢迎所有答案、建议、替代测试请求、阅读材料链接。

我已经做了一段时间的RTFM,谷歌只制作了很少的Advantages of Persistent vs. Non-persistent博客。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-05-05 21:38:02

阿帕奇观点

Apache有一个父进程。此过程创建子进程,该进程将处理向web服务器发出的任何请求。web服务器启动时启动的子进程的初始数量由apache中的StartServers指令配置。随着访问web服务器的请求数量增加,这个数字会根据需要增加,直到到达ServerLimit为止。

PHP和持久连接

如果PHP (以mod_php的形式运行,在脚本执行结束时释放所有资源)现在被告知为请求建立与数据库的持久连接,则即使在脚本完成后也保持此连接。现在持有的连接是请求所处理的apache子进程与数据库服务器之间的连接,并且可以由该子进程处理的任何请求重新使用。

如果由于某种原因(请不要确切地问我为什么),子进程被占用的时间比实际请求长,而另一个请求出现,则父apache进程将此请求重定向到一个(新的)子进程,该进程到目前为止可能还没有建立到数据库的连接。如果必须在脚本执行期间执行,它会引发SID,正如您所观察到的。现在有两个连接由apache的两个不同的子进程持有。

记住..。

重要的是要知道,这也会引起很多麻烦。如果有一个没完没了的循环,或者一个中止的事务,或者其他一些在脚本执行期间甚至是不可预知的错误,连接就会被阻塞,不能被重用。此外,数据库的所有可用连接都可能被使用,但是apache服务器的另一个子进程试图访问数据库。此进程暂时被阻塞,直到数据库或apache释放连接(超时或终止时自愿)。有关此主题的更多信息,请访问本页:http://www.php.net/manual/en/features.persistent-connections.php

我希望我得到了我们在评论谈话中所讨论的所有内容,正确的总结,没有忘记任何东西。如果是的话,请给我一个提示,我会加进去的。:)

编辑:

我刚刚读完了这句话中提到的@MonkeyZeus的文章。它描述了我前面总结的过程,并提供了关于如何优化apache服务器以更好地与持久连接一起工作的有用信息。不过,它可以与oracle数据库后端一起使用,也可以不与oracle数据库后端一起使用。你应该看看:http://www.oracle.com/technetwork/articles/coggeshall-persist-084844.html

票数 48
EN

Stack Overflow用户

发布于 2018-08-10 10:19:43

优势

php的手册页中获取此链接上的持久连接

持久连接是在脚本执行结束时不关闭的链接。当请求持久连接时,PHP会检查是否已经存在相同的持久连接(以前一直处于打开状态)-如果存在,则使用它。如果不存在,则创建链接。

当然,使用持久连接的原因是减少了相当昂贵的连接数量;尽管与大多数其他数据库相比,使用MySQL的连接要快得多。

问题

在使用持久连接时,表锁存在一些问题。

如果脚本由于任何原因无法释放锁,那么使用相同连接的后续脚本将无限期地阻塞,可能需要重新启动httpd服务器或数据库服务器。

另一个原因是mysql 提交在使用事务时。

事务块还将转到下一个脚本,如果在事务块之前脚本执行结束,该脚本将使用该连接。在这两种情况下,您都可以使用register_shutdown_function()注册一个简单的清理函数来解锁表或回滚事务。

我建议你阅读这个问题关于持久连接的优势的文章。

票数 4
EN

Stack Overflow用户

发布于 2014-05-05 19:23:12

PDO这样挺有趣的。即使是同一个用户/访问者也可以创建第二个或第三个实例。在测试我的db查询的性能时,我在本地机器上也发生了同样的事情。

这没什么好担心的,因为这些实例迟早会超时,确切的超时取决于服务器配置。

为什么会这样?如果当前实例很忙,那么将创建一个新实例,而较旧的实例迟早会超时。至少对我来说这是合乎逻辑的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23432948

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档