Postgres libpq如何判断连接是否已终止

时间:2015-04-15 16:26:28

标签: c postgresql libpq

给出以下libpq代码:

PGconn * internalConnection = PQconnectdb("my connection string");
if (PQstatus(internalConnection) != CONNECTION_OK)
{
   // return error on failure
}

// Kill all connections
if(0 == PQsendQuery(internalConnection, "SELECT pid, (SELECT pg_terminate_backend(pid)) as killed from pg_stat_activity"))
{
   // return error on failure
}

以下是:

  1. 建立与服务器的连接。
  2. 执行查询,终止所有连接(包括此连接)。
  3. 如何通过客户端告知连接已被终止?如果我再次运行以下内容:

    PQstatus(internalConnection)
    

    我的结果仍然是CONNECTION_OK

    使用MySQL API我可以检查连接上的mysql_ping以查看连接是否仍然打开,但是在Postgres上,似乎没有类似的方法调用(我可以找到)。

    有关如何从客户端确定连接是否已被终止的任何建议?

1 个答案:

答案 0 :(得分:3)

要查看连接是否通过libpq显示为活动,您可以发送一个空查询字符串:

res = PQexec(conn, "");

并测试结果。

在PostgreSQL协议级别,可以使用简单的Sync消息更有效地完成此操作,但libpq目前尚未公开仅发送Sync的方式。


你不应该这样做。当服务器关闭连接时,它会向客户端发送TCP RST。这应该通知客户端其套接字已关闭。虽然我还没有对它进行测试,但我怀疑调用PQconsumeInput将足以处理连接上的任何剩余数据并注意套接字已被关闭。但是请注意,如果没有要使用的输入,则此函数将阻止等待来自服务器的消息。


顺便说一下,虽然在这种情况下测试连接是合理的(ish),但一般来说这是一个非常糟糕的设计。你永远不应该这样做:

  • 测试连接
  • 运行查询
  • 假设成功

因为在测试连接和实际执行查询或查询之间存在竞争。更不用说查询因其他原因而失败的事实。

您的应用程序总是能够处理失败的事务,并且能够重试它。您应该有适当的逻辑来中止和重试瞬态错误上的事务,或者如果连接本身是坏的则重新连接。

PostgreSQL的libpq可以让它比目前对用户更容易。它应该公开一些函数来测试SQLState以查看它是否可能是瞬态的,例如,因此应用程序可以使用单个调用来重试死锁中止,​​序列化失败等。现在你必须自己做。