↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 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
开发快照。 PostgreSQL 20devel 尚未正式发布,内容仍可能变化。

32.8. 异步通知 #

PostgreSQL 通过 LISTEN 和 NOTIFY 命令提供异步通知。客户端会话可使用 LISTEN 命令注册其感兴趣的特定通知通道(也可以用 UNLISTEN 命令停止监听)。当任何会话执行带有该通道名的 NOTIFY 命令时,所有监听该通道的会话都会异步收到通知。还可以传递一个“载荷”字符串,向监听者传递附加数据。

libpq 应用把 LISTEN、UNLISTEN 和 NOTIFY 命令作为普通 SQL 命令提交。随后通过调用 PQnotifies 来检测 NOTIFY 消息的到达。

函数 PQnotifies 从已收到但尚未处理的服务器通知消息列表中返回下一条通知。没有待处理通知时返回空指针。一旦 PQnotifies 返回一条通知,该通知就被视为已处理,并从通知列表中移除。

PGnotify *PQnotifies(PGconn *conn);

typedef struct pgNotify
{
    char *relname;              /* 通知通道名称 */
    int  be_pid;                /* 发送通知的服务器进程 ID */
    char *extra;                /* 通知载荷字符串 */
} PGnotify;

处理完 PQnotifies 返回的 PGnotify 对象后,务必使用 PQfreemem 释放它。只需释放 PGnotify 指针;relname 和 extra 字段并非独立分配。(这些字段名称是历史遗留的;尤其是,通道名称与关系名称不必有任何关联。)

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

PQnotifies 实际上并不从服务器读取数据;它只是返回之前已被其他 libpq 函数读取的消息。在较早版本的 libpq 中,及时收到 NOTIFY 消息的唯一方法是不断提交命令,哪怕是空命令,然后在每次 PQexec 后检查 PQnotifies。虽然这种方法仍然有效,但由于浪费处理能力,现已弃用。

当没有需要执行的实际命令时,一种更好的检查 NOTIFY 消息的方法是调用 PQconsumeInput,然后检查 PQnotifies。你可以使用 select() 等待服务器数据到达,这样在无事可做时就不会浪费 CPU 资源(参见 PQsocket 以获得可传给 select() 的文件描述符)。注意不管是用 PQsendQuery/PQgetResult 提交命令还是简单地使用 PQexec,这种方法都能正常工作。不过,你应该记住在每次 PQgetResult 或 PQexec 之后检查 PQnotifies,看看在命令的处理过程中是否有通知到达。

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.