首页 > 解决方案 > PHP 致命错误:未捕获的 HY000:“自适应服务器连接超时”

问题描述

我正在运行一个 PHP 脚本来连接到 MsSQL 并执行一个长时间运行的存储过程。该过程需要一个我通过此脚本传入的 ID。我遍历所有 ID 数组并调用此过程。但是,对于某些 ID,此过程需要大量时间才能运行并超时。我将 ATTR_TIMEOUT PDO 属性设置为 600 秒。我在 try catch 块中有所有 PDO 语句。尽管如此,我还是得到了这个未捕获的异常。这是我的示例代码:(请忽略 new_statement 参数。我在这里使用了假人。它是有效的并且运行良好)

try {
$statement = PDO::new_statement('DB', $sql, 0, false, false, [PDO::ATTR_TIMEOUT => 600]);
$this->execute($statement);
} catch (Exception $e) {
$logger->error("Error for ID: " . $id);
}

这适用于大多数 ID。对于一些长时间运行的 ID,它会失败。如果执行查询时出现 TIMEOUT 问题,我希望记录该错误。但是我看到了这个例外:

PHP致命错误:未捕获的HY000 [“HY000”,20003,“自适应服务器连接超时[20003](严重性6)

有人可以帮我解决这个问题。

标签: phpsql-serverpdo

解决方案


将选项传递给 PDO 构造函数:

$pdo = new PDO(
    "mysql:host=$host;dbname=$dbname", 
    $username, 
    $password,
    array(
        PDO::ATTR_TIMEOUT => "(seconds)",
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    )
);

如果这没有帮助,您可以尝试手动设置 connect_timeoutphp.ini或使用 ini_set()

mysql.connect_timeout = "(seconds)"

如果驱动使用sockets进行基本连接,并设置超时,则需要使用socket(流)超时功能

ini_set("default_socket_timeout", "(秒)");

你也应该知道

PDO::ATTR_TIMEOUT:以秒为单位指定超时持续时间。并非所有驱动程序都支持此选项,其含义可能因驱动程序而异。例如,sqlite 在放弃获取可写锁之前将等待到这个时间值,但其他驱动程序可能会将其解释为连接或读取超时间隔。


推荐阅读