完全理解PDO ATTR_PERSISTENT

Mon*_*eus 23 php oracle pdo oracle10g

题:

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


环境:

网络服务器

  • Windows 7 x64
  • 双核,16GB RAM
  • Apache 2.2.17
  • PHP 5.3.5
  • 通过DSN字符串连接IP地址,端口,服务名称等...
  • 没有用于DB conn的ODBC(现在尝试创建一个2小时,感谢Oracle!)

DB服务器

  • Linux上的Oracle 10g
  • 多核,4GB RAM
  • 专门为我的网络应用创建的用户名(是的,这是假的)
    • user:webuser

我的理解/观察:

非持久连接

<?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?

?>
Run Code Online (Sandbox Code Playgroud)
  • 脚本可靠地花费大约.09秒来执行框架开销等...

持久的联系

<?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

?>
Run Code Online (Sandbox Code Playgroud)
  • 使用框架开销等初始访问时脚本需要大约0.12秒才能执行...
  • 后续执行需要〜.04

问题:

我访问该页面并webuser得到一个SID=1

我的同事访问该页面并为访问此页面的新计算机webuser获得额外的SID=2< - 冲洗,重复和增加SID

难道不应该重新使用新访客SID=1吗?


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

我有一段时间的RTFM,谷歌搜索只产生了微薄的Advantages of Persistent vs. Non-persistent博客.

fun*_*der 35

阿帕奇的观点

Apache有一个父进程.此过程创建子进程,以处理进入Web服务器的任何请求.Web服务器启动时启动的初始子进程数由StartServersapache配置中的指令配置.根据需要,该数量会增加,直到ServerLimit达到Web服务器的请求数量增加.

PHP和持久连接

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

如果由于某种原因(不要问我确切原因),子进程占用的时间比实际请求长,而另一个请求进来,则父apache进程将此请求重定向到可能尚未建立的(新)子进程到目前为止与数据库的连接.如果必须在执行脚本期间,它会像您所观察到的那样提升SID.现在,两个不同的apache子进程有两个连接.

请记住......

重要的是要知道,这也会带来很多麻烦.如果在脚本执行期间存在无限循环或中止事务或某些其他可能甚至是不可预测的错误,则连接被阻止且无法重新使用.此外,可能会使用数据库的所有可用连接,但是apache服务器的另一个子进程正在尝试访问数据库.此过程暂时被阻止,直到数据库或apache释放连接(超时或自动终止).有关此主题的更多信息,请访问此页面:http://www.php.net/manual/en/features.persistent-connections.php

我希望我能在我们的评论对话中正确总结所讨论的一切,并且不会忘记任何事情.如果是这样,请给我一个提示,我会添加它.:)

编辑:

我刚刚读完中提到的文章@MonkeyZeus 此评论.它描述了我在上面总结的过程,并提供了有关如何优化Apache服务器以便与持久连接一起更好地工作的有用信息.但是,无论有没有oracle数据库后端,它都可以使用.你应该看看:http://www.oracle.com/technetwork/articles/coggeshall-persist-084844.html