codecamp

PostgreSQL 异步提示

PostgreSQL通过LISTENNOTIFY命令提供了异步通知。一个客户端会话用LISTEN命令在一个特定的通知频道中注册它感兴趣的通知(也可以用UNLISTEN命令停止监听)。当任何会话执行一个带有特定频道名的 NOTIFY命令时,所有正在监听该频道的会话会被异步通知。可以传递一个载荷字符串来与监听者沟通附加的数据。

libpq应用把LISTENUNLISTENNOTIFY命令作为通常的 SQL 命令提交。 随后通过调用PQnotifies. 来检测NOTIFY消息的到达。

函数PQnotifies从来自服务器的未处理通知消息列表中返回下一个通知。如果没有待处理的信息则返回一个空指针。一旦PQnotifies返回一个通知,该通知会被认为已处理并且将被从通知列表中删除。

PGnotify *PQnotifies(PGconn *conn);

typedef struct pgNotify
{
    char *relname;              /* notification channel name */
    int  be_pid;                /* process ID of notifying server process */
    char *extra;                /* notification payload string */
} PGnotify;

在处理完PQnotifies返回的PGnotify对象后,别忘了用PQfreemem把它释放。 释放PGnotify指针就足够了; relnameextra域并不代表独立分配的内存(这些域的名称是历史性的,尤其是频道名称与关系名称没有什么联系)。

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

PQnotifies实际上并不从服务器读取数据;它只是返回被另一个libpq函数之前吸收的消息。 在以前的libpq版本中,及时收到NOTIFY消息的唯一方法是持续地提交命令,即使是空命令也可以,并且在每次 PQexec 后检查PQnotifies。 虽然这个方法还能用,但是由于太过浪费处理能力已被废弃。

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


PostgreSQL 快速路径接口
PostgreSQL COPY命令相关的函数
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

PostgreSQL SQL语言

PostgreSQL 服务器管理

PostgreSQL 客户端接口

PostgreSQL 服务器编程

PostgreSQL 参考

PostgreSQL 内部

PostgreSQL 附录

PostgreSQL 参考书目

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }