充分了解PDO ATTR_PERSISTENT [英] Fully Understanding PDO ATTR_PERSISTENT

查看:325
本文介绍了充分了解PDO ATTR_PERSISTENT的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What are the rules/logic behind persistent connection management when using PDO?

Web服务器

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

数据库服务器

  • Linux上的Oracle 10g
  • 具有4GB RAM的多核
  • 专门为我的网络应用创建的用户名(是的,是假的)
    • 用户:webuser
    • Oracle 10g on Linux
    • Multi-core with 4GB RAM
    • Username specifically created for my web app (yes, it's fake)
      • 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?
      
      ?>
      

      • 脚本可靠地花费了约.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
        
        ?>
        

        • 脚本在初次访问时需要花费〜.12秒的时间,而框架的开销等等.
        • 后续执行需要〜.04
          • Script takes ~.12 seconds to execute upon initial visit with framework overhead, etc...
          • Sub-sequent executes take ~.04
          • 我访问了页面,webuser得到了SID=1

            I visit the page and webuser gets a SID=1

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

            My colleague visits the page and webuser gets an additional SID=2 <- rinse, repeat, and increment SID for new computers visiting this page

            新访客不是要重新使用SID=1吗?

            Shouldn't a new visitor be re-using SID=1?

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

            All answers, suggestions, requests for alternate testing, links to reading material are welcomed.

            我已经使用RTFM了一段时间,而Googling只制作了微薄的Advantages of Persistent vs. Non-persistent博客.

            I have RTFM'ed for a while and Googling has only produced meager Advantages of Persistent vs. Non-persistent blogs.

            推荐答案

            Apache的观点

            Apache有一个父进程.此过程将创建子进程,该子进程将处理到达Web服务器的所有请求. Web服务器启动时启动的子进程的初始数量由apache配置中的StartServers指令配置.这个数字根据需要增加,直到到达ServerLimit为止,越来越多的请求到达Web服务器.

            Apaches point of view

            Apache has one parent process. This process creates child processes that will handle any requests coming to the web server. The initial amount of child processes being started when the web server starts is configured by the StartServers directive in the apache configuration. The number goes up as needed with a raising amount of requests hitting the web server until ServerLimit is reached.

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

            If PHP (ran as mod_php, as CGI all resources are freed at the end of script execution) is now being told to establish a persistent connection with a database for a request, this connection is hold even after the script finishes. The connection being now hold is a connection between the apache child process which the request was handled by and the database server and can be re-used by any request that is being handled by this exact child process.

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

            If, for some reason (do not ask me exactly why), the child process is being occupied longer than the actual request and another request comes in, the parent apache process redirects this request to a (new) child process which may has not established a connection to the database up to this time. If it has to during the execution of the script, it raises the SID as you have observed. Now there are two connections be hold by two different child processes of apache.

            重要的是要知道,这也会引起很多麻烦. 如果在脚本执行过程中存在无限循环,事务异常终止或其他甚至是无法预料的错误,则连接将被阻止并且无法重新使用. 也有可能使用了数据库的所有可用连接,但是apache服务器的另一个子进程正在尝试访问数据库. 该过程暂时被阻塞,直到数据库或Apache释放连接(超时或通过终止自愿). 此页面上有关此主题的任何其他信息: http://www.php .net/manual/en/features.persistent-connections.php

            It is important to know, that this can also cause a lot of trouble. If there is an endless loop or an aborted transaction or some other may be even unpredictable error during the script execution, the connection is blocked and can not be re-used. Also it could happen that all of the available connections of the database are used, but there is another child process of the apache server trying to access the database. This process is blocked for the time being until a connection is freed by the database or apache (timeout or voluntarily by termination). Any further information about this topic on this page: http://www.php.net/manual/en/features.persistent-connections.php

            我希望我对我们在评论对话中讨论的所有内容都进行了正确总结,并且不要忘记任何内容. 如果是这样,请给我一个提示,我会添加它. :)

            I hope I got all that we have discussed in our comment conversation summarized correctly and did not forget anything. If so, please, leave me a hint and I will add it. :)

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

            I just finished reading the article @MonkeyZeus mentioned in this comment. It describes the process I summarized above and provides useful information on how to optimize your apache server to work better together with persistent connections. It can be used with or without oracle database backends, though. You should give a look: http://www.oracle.com/technetwork/articles/coggeshall-persist-084844.html

            这篇关于充分了解PDO ATTR_PERSISTENT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆