↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 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.1 已于 2006 年 4 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

1.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(),看查询处理期间是否有通知到来。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。