我应该在获取后手动关闭数据库连接和语句的游标吗?

Posted

技术标签:

【中文标题】我应该在获取后手动关闭数据库连接和语句的游标吗?【英文标题】:Should I manually close DB Connection and Statement's cursor's after a fetch? 【发布时间】:2015-12-30 23:13:04 【问题描述】:

我正在使用 Silex 和 Doctrine DBAL 使用 mysql 数据库构建一些东西。

我想知道在完成后关闭语句和数据库连接的游标是否被认为是最佳做法。例如:

$sql = '
    SELECT
        `id`, `userid`, `name`, `content` 
    FROM 
        `pages` p 
    WHERE 
        p.`userid` in (?)'; 

$stmt = $conn->executeQuery(
    $sql,
    [$userIds],
    [\Doctrine\DBAL\Connection::PARAM_INT_ARRAY]
);

$rows = $stmt->fetchAll();

$stmt->closeCursor();

$conn->close();

我找不到任何这样的例子。 Silex 和 Doctrine 文档都没有使用这些语句,但它们的存在是有原因的,对吗?

【问题讨论】:

【参考方案1】:

$stmt->closeCursor() appears 只是 PDOStatement::closeCursor() 的包装,如果需要,您可以重新执行查询:

PDOStatement::closeCursor() 释放与服务器的连接,因此 可以发出其他 SQL 语句,但将语句留在 状态,使其能够再次执行。

此方法对于不支持的数据库驱动程序很有用 在先前执行时执行 PDOStatement 对象 PDOStatement 对象仍有未提取的行。 如果您的数据库驱动程序 受此限制,问题可能会表现在 乱序错误。

在您发布的示例中,您没有执行多个查询,而是在之后立即关闭连接。因此,调用它是没有好处的。如果您真的担心内存使用情况,将$stmt 设置为null 应该更有效。

Connection::close() appears 只是将对象上的连接设置为空:

/**
 * Closes the connection.
 *
 * @return void
 */
public function close()

    $this->_conn = null;
    $this->_isConnected = false;

它释放了一些内存,因此比调用它更好。但是,我希望好处可以忽略不计,因为无论如何脚本终止时它都会关闭。

【讨论】:

嗯,是的,但是$conn->close(); 调用也没有在他们的文档中列出。我的问题是关于关闭数据库... @Tieme,也许我没有关注 - $conn 不是 Connection 的实例吗?这不是你指的“db”吗? 是的,它是Connection 的一个实例,而且确实是我所指的数据库(连接)。 如果文档说:PDOStatement::closeCursor() frees up the connection to the server so that other SQL statements may be issued 那么应该调用它对吗? @Tieme,根据我复制的内容,我明白您为什么会这么认为。我已经更新了答案——但PDOStatement::closeCursor() 的目的更多的是支持边缘数据库而不是优化。 IMO,关于设置 $stmt = null; 的注释是多余的,但应该值得尝试关闭光标。

以上是关于我应该在获取后手动关闭数据库连接和语句的游标吗?的主要内容,如果未能解决你的问题,请参考以下文章

Socket.io - 客户端断开连接后手动重新连接

使用 SessionFactoryUtils 时我应该关闭连接吗

Java 技术篇 - 连接oracle数据库执行sql使用close()关闭createStatement()无效无法清除游标缓存问题解决,报“ORA-01000: 超出打开游标的最大数“错误解决方法

python中脚本怎么执行sql语句?

python中脚本怎么执行sql语句?

Python链接Mssql之Python库pymssql