PHP Conference Japan 2024

pg_connection_busy

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

pg_connection_busy 获取连接是否繁忙

描述

pg_connection_busy(PgSql\Connection $connection): bool

pg_connection_busy() 用于确定连接是否繁忙。如果繁忙,则表示先前的查询仍在执行。如果在连接上使用 pg_get_result(),它将被阻塞。

参数

connection

一个 PgSql\Connection 实例。

返回值

如果连接繁忙,则返回 true,否则返回 false

变更日志

版本 描述
8.1.0 connection 参数现在期望一个 PgSql\Connection 实例;以前,期望的是一个 资源

范例

示例 #1 pg_connection_busy() 示例

<?php
$dbconn
= pg_connect("dbname=publisher") or die("Could not connect");
$bs = pg_connection_busy($dbconn);
if (
$bs) {
echo
'connection is busy';
} else {
echo
'connection is not busy';
}
?>

参见

添加注释

用户贡献的注释 2 条注释

levi at alliancesoftware dot com dot au
15 年前
pg_connection_busy() 返回 true 并不一定意味着有结果正在等待 pg_get_result();在导致任何类型的 postgres 错误的查询之后,它也会保持一段时间为 true。(参见 http://bugs.php.net/bug.php?id=36469
VLroyrenn
5 年前
这里似乎没有任何关于如何使用此函数的文档,我担心大多数尝试此操作的人在等待时将默认使用繁忙循环(在这种情况下,pg_get_result 会更好,因为它只是阻塞直到结果准备就绪)或睡眠循环,如果尝试在一段时间后取消查询。

libPq 的 C 文档建议使用 PQisBusy(pg_connection_busy 的 C 等价物)通过等待套接字来实现,这允许您在状态在一段时间后未更改时超时,但在状态更改时立即做出反应。如果您想在超时后取消,则可以执行以下操作

<?php
class SomeKindOfTimeoutException extends Exception { }

class
SomeKindOfSQLErrorException extends Exception { }

function
query_with_timeout($conn, $query, $timeout_seconds) {
assert(pg_get_result($conn) === false); // 确保没有任何内容正在运行

$socket = [pg_socket($conn)];
$null = [];

$dispatch_ok = pg_send_query($conn, $query);

$still_running = pg_connection_busy($conn);

while(
$still_running) {
// https://postgresql.ac.cn/docs/current/libpq-async.html
// "一个使用这些函数的典型应用程序将有一个主循环,该循环使用 select() 或 poll() 来等待它必须响应的所有条件。"
// "其中一个条件将是从服务器接收到的输入,就 select() 而言,这意味着在由 PQsocket 标识的文件描述符上可读数据。"
// PQisBusy 映射到 pg_connection_busy
stream_select($socket, $null, $null, $timeout_seconds); // 将在该套接字上等待,直到发生这种情况或超时。
$still_running = pg_connection_busy($conn); // 超时时为 false,完成时为 true

// 你可以继续轮询,这只是在第一次循环时立即中断并抛出异常
if ($still_running) {
$cancel_ok = pg_cancel_query($conn);
throw new
SomeKindOfTimeoutException("TIMEOUT");
}
}

$res = pg_get_result($conn);

try {
$error_msg = pg_result_error($res);
if (
$error_msg) throw new SomeKindOfSQLErrorException($error_msg);

return
pg_fetch_all($res);
} finally {
pg_free_result($res);
}
}

$conn_string = "host=localhost port=5433 dbname=postgres";
$db = pg_connect($conn_string);

query_with_timeout($db, "SELECT pg_sleep(10)", 3); // 将抛出异常
?>
To Top