pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
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(),看查询处理期间是否有通知到来。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。