pg_connection_busy() 返回 true 并不一定意味着有结果在等待 pg_get_result();它在导致任何类型的 postgres 错误的查询完成后也会保持 true。(参见 http://bugs.php.net/bug.php?id=36469)
(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)
pg_connection_busy — 获取连接是否繁忙
pg_connection_busy() 确定连接是否繁忙。如果繁忙,则先前查询仍在执行。如果对连接使用 pg_get_result(),它将被阻塞。
版本 | 描述 |
---|---|
8.1.0 | The connection parameter expects an PgSql\Connection instance now; previously, a resource was expected. |
示例 #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';
}
?>
pg_connection_busy() 返回 true 并不一定意味着有结果在等待 pg_get_result();它在导致任何类型的 postgres 错误的查询完成后也会保持 true。(参见 http://bugs.php.net/bug.php?id=36469)
这里似乎没有关于如何使用此函数的文档,而且我相信大多数尝试使用此函数的人会默认在等待时使用繁忙循环(在这种情况下 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); // 将抛出
?>