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

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

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 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 / 7.0 / 6.5 / 6.4
历史版本。 PostgreSQL 8.3 已结束支持。 请参阅 当前版本手册.

NOTIFY

NOTIFY — 发出一个通知

大纲

NOTIFY name        

描述

NOTIFY 命令向当前数据库中曾为指定通知名执行过 LISTEN name 的每个客户端应用发送一个通知事件。

NOTIFY为访问同一个PostgreSQL数据库的一组进程提供了一种简单的进程间通信机制。如果需要传递结构化数据,也可以借助数据库中的表,把附加数据(而不只是通知名)从通知发送者传递给一个或多个监听者,从而构建更高层的机制。

传递给客户端的通知事件信息包括:通知名以及发出通知的会话对应的服务器进程PID。在某个数据库中使用哪些通知名以及各自含义,由数据库设计者自行决定。

常见的做法是让通知名与数据库中的某个表同名,而通知事件基本上意味着:“我改动了这张表,去看看有什么新变化”。不过,NOTIFY和LISTEN命令并不会强制这种关联。例如,数据库设计者可以使用多个不同的通知名,来标识同一张表上的不同类型的变更。

当NOTIFY用于表明某张特定表发生变化时,一种很有用的编程技巧是把NOTIFY放进由表更新触发的规则中。这样一来,每当表发生变化时就会自动发出通知,应用程序员也不容易忘记这么做。

NOTIFY会以几种重要方式与 SQL 事务交互。首先,如果在事务内部执行NOTIFY,那么只有在事务提交之后,通知事件才会被递送;如果事务被中止,则其中所有命令都不会生效,NOTIFY也不例外。这种行为是合理的,但如果你期望通知立即送达,可能会感到意外。其次,如果某个正在监听的会话在事务内部收到了通知信号,那么在该事务结束(提交或中止)之前,通知事件都不会递送给它所连接的客户端。原因同样在于:如果通知在事务内部就已递送,而该事务后来又被中止,我们会希望通知也能被撤销,但服务器一旦把通知发送给客户端,就无法再把它“收回”。因此,通知事件只会在事务之间递送。由此得出的结论是,使用NOTIFY做实时信号的应用,应尽量让事务保持短小。

NOTIFY在一个重要方面的行为类似 Unix 信号:如果在短时间内多次发出同一通知名的信号,接收者可能对多次执行的NOTIFY只收到一个通知事件。因此,依赖收到通知的数量并不是一个好主意。正确的做法是用NOTIFY唤醒需要关注某事的应用,而用一个数据库对象(例如序列)来跟踪发生了什么以及发生了多少次。

执行NOTIFY的客户端自己同时也在监听同一通知条件,这是很常见的情形。在这种情况下,它会像其他监听会话一样收到一个通知事件。根据应用逻辑,这可能导致无用功,例如再次读取自己刚刚写入更新的数据库表。要避免这种额外工作,可以检查通知事件消息中提供的发出通知的服务器进程PID,是否与当前会话自身的PID(可通过libpq获得)相同。如果二者相同,就说明这是当前会话自己发出的通知回送给自己,可以直接忽略。(尽管前一段有那样的说法,但这是一种安全的技术:PostgreSQL会把自身通知与来自其他会话的通知分开保存,因此忽略自己的通知并不会让你错过来自外部的通知。)

参数

name

要发信号的通知名称(任意标识符)。

示例

在psql中配置并执行一组 listen/notify 操作:

LISTEN virtual;
NOTIFY virtual;
Asynchronous notification "virtual" received from server process with PID 8448.

兼容性

SQL 标准中没有NOTIFY语句。

报告文档问题

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