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

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

已结束支持的版本: 7.0 / 6.4
历史版本。 PostgreSQL 7.0 已结束支持。 请参阅 当前版本手册.

53.5. 异步通知

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

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

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

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

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

    注意

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

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

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

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

报告文档问题

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