您的位置:寻梦网首页编程乐园数据库PostgreSQL 7.2 Documentation

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[NAMEDATALEN];       /* 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 时间. (参阅 PQsocket() 获取用于 select() 的文件描述符.) 注意这种方法不管你使用 PQsendQuery / PQgetResult 还是简单的 PQexec 来执行查询都能工作.不过,你应该记住在每次 PQgetResult PQexec 后检查 PQnotifies() ,看看在处理查询的过程中是否有通知到达.