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

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 7.3 已结束支持。 请参阅 当前版本手册.

1.6. 异步通知 #

PostgreSQL 通过 LISTEN 和 NOTIFY 命令支持异步通知。后端用 LISTEN 命令注册它对某个特定通知条件的兴趣(并可以用 UNLISTEN 命令停止监听)。当任何后端执行带该条件名的 NOTIFY 命令时,所有监听该条件的后端都会被异步通知。通知者不会向监听者传递任何附加信息。因此,通常需要通信的任何实际数据都通过一个数据库关系传递。条件名通常与相关的关系同名,但并不要求必须有相关的关系。

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

  • PQnotifies 从后端发来的尚未处理的通知消息列表中返回下一条通知。没有待处理的通知时返回 NULL。一条通知被 PQnotifies 返回后即视为已处理,并会从通知列表中移除。

    PGnotify* PQnotifies(PGconn *conn);
    
    typedef struct pgNotify {
        char *relname;              /* name of relation containing data */
        int  be_pid;                /* process id of backend */
    } PGnotify;

    处理完 PQnotifies 返回的 PGnotify 对象后,务必用 free() 释放它,以避免内存泄漏。

    注意

    在 PostgreSQL 6.4 及之后的版本中,be_pid 是发出通知的后端的 PID,而在较早的版本中它总是你自己的后端的 PID。

第二个示例程序演示了异步通知的使用。

PQnotifies() 并不真正读取后端数据;它只是返回先前被其他 libpq 函数吸收的消息。在 libpq 的早期版本中,确保及时收到 NOTIFY 消息的唯一方法是不断地提交查询(哪怕是空查询),然后在每次 PQexec() 之后检查 PQnotifies()。这种方法虽然仍然有效,但由于浪费处理能力已被弃用。

在没有有用查询可提交时检查 NOTIFY 消息的更好办法是调用 PQconsumeInput(),然后检查 PQnotifies()。可以用 select() 等待后端数据到达,这样除非有事可做就不会消耗 CPU。(获取用于 select() 的文件描述符号的方法见 PQsocket()。)注意,无论你用 PQsendQuery/PQgetResult 提交查询还是直接用 PQexec,这样做都没有问题。但应记住在每次 PQgetResult 或 PQexec 之后检查 PQnotifies(),看查询处理期间是否有通知到来。

报告文档问题

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