【问题标题】:How to use Persistent Connection of PDO? [duplicate]如何使用 PDO 的持久连接? [复制]
【发布时间】:2011-05-09 11:12:12
【问题描述】:

我有以下代码,并在 Firefox 中刷新了这个网页 5 次,然后 MySQL 向我显示了 5 个连接。根据 PDO 手册,

持久连接未关闭 在脚本的末尾,但是 缓存并在另一个脚本时重新使用 使用相同的请求连接 证书。持久连接 缓存允许您避免开销 每建立一个新的连接 脚本需要与 数据库,从而实现更快的网络 应用。

我使用了相同的凭据,但是 MYSQL 连接的数量不断增加。即使尝试关闭与$db = null 的连接也无法关闭连接。 我的代码有什么问题?

<?php
try {
 $dbh = new PDO('mysql:host=127.0.0.1;dbname=lingtong', 'root', 'xxxxxx', array(PDO::ATTR_PERSISTENT => true));
 foreach ($dbh->query('SELECT * from agent') as $row) 
  print_r($row);
 $dbh = null;
} catch (PDOException $e) {
 print "Error! : " . $e->getMessage() . "<br/>";
 die();
}

【问题讨论】:

  • 什么“不起作用”?关闭连接还是移除持久性?
  • php.net/manual/en/pdo.connections.php 看最后一个注释。你会遇到这种情况吗?
  • 您获取连接数的方法是什么?显示进程列表或?
  • 这些连接缓存究竟在哪里???即使您没有缓存机制,这也有效?
  • 看来您需要关闭游标并将null分配给最后一个语句对象以及关闭连接

标签: php mysql pdo


【解决方案1】:

这个问题很老了,但如果我贡献就可以了。我认为您需要实现一个单例类来处理数据库连接我将在下面编写一个示例类..

<?php
class DB{

//set the connection property to private to prevent direct access 
private static $conn;

//now since we dont want to reinstiate the class anytime we need it, lets also set the constructor to private 
private function __construct(){}

//now lets create our method for connecting to the database 
public static function connect(){

//now lets check if a connection exists already in our $conn property, then we should return it instead of recreating a new connection 
if(!empty(self::$conn)){
return self::$conn;
}//end if 

//upon reaching here means the $conn property is empty so lets create a new connection 

try {
 $dbh = new PDO('mysql:host=127.0.0.1;dbname=lingtong', 'root', 'xxxxxx', array(PDO::ATTR_PERSISTENT => true));

//lets now assign the database connection to our $conn property 
self::$conn = $dbh;

//return the connection 
return $dbh;

} catch (PDOException $e) {
 print "Error! : " . $e->getMessage() . "<br/>";
 die();
}

}//end method 

}//end class

?>

我们的单例类只能建立一个连接并重用它,让我们看看如何使用我们的类

<?php 
$dbh = DB::connect();

foreach ($dbh->query('SELECT * from agent') as $row){ 
  print_r($row);
}
?>

【讨论】:

  • 那么你贡献了什么?您只是创建了一个单例,没有解释原因,也没有涉及持久连接的主题。你的代码有什么帮助?你知道什么是持久连接,为什么使用它们以及单例如何帮助解决这个问题?
  • @Mjh 我是我弄错了还是你投了错误的答案?
  • @Mjh 我知道什么是持久连接,除了我在类中添加了持久支持,而且更重要的是,持久连接和单例类都针对可伸缩性,我们在这里是为了互相帮助最好的什么可能对其他人有帮助,再次,代码已经解释,那是我评论了代码,谢谢
  • @JonatanCloutier - 我没有否决错误的答案。我对你的投票投了反对票,因为你不知道什么是持久连接,你认为 OP 正在使用 Apache,而你提供了错误的答案。无意冒犯。
  • 我一直在寻找其他 Stack Overflow 答案,这是我发现的最好的 PDO 类。我不同意上面的其他人,因为它缺乏解释。代码中的cmets很清楚。我发现它很有帮助。
【解决方案2】:

看来您需要关闭游标并释放(分配 null)到最后一个 pdo 语句对象以及关闭连接。

此外,了解持久连接的重要一点是它们会持续存在,但不能保证两者都不会:

  • 在进一步的脚本执行中返回您的最后一个连接处理程序
  • 也不要重用之前的连接,如果它仍然“忙”的话。忙碌可能意味着脚本中、超时等...连接实例化可能会持续不断...请参阅Fully Understanding PDO ATTR_PERSISTENT

【讨论】:

    【解决方案3】:

    据我所知,您可能不需要它:

    1. 您在本地主机上,因此连接速度非常快,您不会从连接缓存中节省很多
    2. 由于 Apache 的底层原理,您有许多线程来响应客户端请求,并且由于这些多线程,连接在单个线程中是持久的,而不是在所有线程上共享,因此您将看到您的连接数在 mysql 中启动,直到达到 apache 的 ThreadLimit
    3. 持久连接可能会导致您的应用出现 dbLock 或 tableLock 问题

    如果你仍然认为你真的需要持久连接,那么现在你可能想要做更多的研究

    【讨论】:

    • 投反对票的原因:是否有人在本地主机上无关紧要。非持久连接使用文件描述符。非持久连接在每个 http 请求上启动连接握手。 2) Apache 或 nginx 保持每个线程的连接并且它们执行一次握手 - 这意味着每个后续请求 不会 必须经过这个开销。这就是您想要的。连接上升的原因是因为 Apache 是一个写得很糟糕的软件,无法正确清理。 3)WTF?!您刚刚删除了包含 0 个事实的随机陈述。
    • @Mjh 谢谢,至少我可以理解为什么它被否决了,而我不能不发表评论
    • 答案可以改进和编辑,在这种情况下你会得到我的支持,我建议你在其中添加一些额外的信息。问题是没有什么是非黑即白的,持久连接有其用处,非持久连接也有用。持久连接最好与php-fpm 一起使用,而非持久连接应该与Apache 和mod_php 一起使用,因为Apache 往往会搞砸。诸如php-fpm 之类的 FastCGI 应用程序由于持久连接而变得更快(呃),而不仅仅是针对 MySQL。
    • 我只需要刷新一下思路,我已经有几年没有在这个级别上工作了。同时,对于搜索此主题的人来说,这表达了我回答的主要部分stackoverflow.com/questions/50303/…
    • 这个答案现在已经 8 岁了,而且它甚至都不正确。人们通常会在不考虑事实的情况下阅读他们想要真实和支持的内容。如今,应用程序的构建要好得多,并且具有更多的前瞻性。如果您想要一个快速的应用程序,您将使用持久连接,因为它总是更快地连接一次,而不是在每次请求时连接/断开连接(这实际上会破坏数据库并降低性能)。
    猜你喜欢
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    • 2019-09-23
    • 2012-08-06
    相关资源
    最近更新 更多