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 | 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';
}
?>
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); // 将抛出异常
?>