支持的版本:当前 (17) / 16 / 15 / 14 / 13
开发版本:devel
不支持的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

32.9. 异步通知 #

PostgreSQL 通过 LISTENNOTIFY 命令提供异步通知。客户端会话通过 LISTEN 命令注册对特定通知通道的兴趣(并可以使用 UNLISTEN 命令停止监听)。当任何会话执行具有该通道名称的 NOTIFY 命令时,所有监听特定通道的会话都将异步收到通知。可以传递一个负载字符串,以将额外的数据传递给监听器。

libpq 应用程序将 LISTENUNLISTENNOTIFY 命令作为普通的 SQL 命令提交。随后可以通过调用 PQnotifies 来检测 NOTIFY 消息的到达。

函数 PQnotifies 从服务器接收到的未处理通知消息列表中返回下一个通知。如果没有待处理的通知,则返回空指针。一旦从 PQnotifies 返回通知,则认为该通知已被处理,并将从通知列表中删除。

PGnotify *PQnotifies(PGconn *conn);

typedef struct pgNotify
{
    char *relname;              /* notification channel name */
    int  be_pid;                /* process ID of notifying server process */
    char *extra;                /* notification payload string */
} PGnotify;

在处理 PQnotifies 返回的 PGnotify 对象后,请务必使用 PQfreemem 释放它。释放 PGnotify 指针就足够了;relnameextra 字段不代表单独的分配。(这些字段的名称是历史遗留的;特别是,通道名称不必与关系名称有任何关系。)

示例 32.2 给出了一个示例程序,说明了异步通知的使用。

PQnotifies 实际上不从服务器读取数据;它只是返回先前被另一个 libpq 函数吸收的消息。在较旧版本的 libpq 中,确保及时收到 NOTIFY 消息的唯一方法是不断提交命令(即使是空命令),然后在每次 PQexec 之后检查 PQnotifies。虽然这仍然有效,但它已被弃用,因为它浪费了处理能力。

当没有有用的命令要执行时,检查 NOTIFY 消息的更好方法是调用 PQconsumeInput,然后检查 PQnotifies。 您可以使用 select() 等待来自服务器的数据到达,从而在没有事情要做时不会占用CPU资源。(请参阅 PQsocket 以获取与 select() 一起使用的文件描述符编号。)请注意,无论您是使用 PQsendQuery/PQgetResult 提交命令,还是直接使用 PQexec,这都将正常工作。但是,您应该记得在每次 PQgetResultPQexec 之后检查 PQnotifies,以查看在命令处理期间是否有任何通知到来。

提交更正

如果您在文档中发现任何不正确、与您特定功能的使用经验不符或需要进一步澄清的地方,请使用此表单报告文档问题。