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

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 / 7.0 / 6.5 / 6.4
历史版本PostgreSQL 7.1 已于 2006 年 4 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

NOTIFY

NOTIFY — 向所有正在监听某个通知条件的前端和后端发信号

大纲

NOTIFY name        
  

Inputs

notifyname

要发信号的通知条件。

Outputs

NOTIFY

确认 notify 命令已执行。

Notify events

事件被送达正在监听的前端;每个前端应用是否响应以及如何响应取决于它的程序设计。

描述

NOTIFY 命令向当前数据库中每个此前已为指定通知条件执行过 LISTEN notifyname 的前端应用发送一个通知事件。

传递给前端的通知事件信息包括通知条件名和发出通知的后端进程的 PID。由数据库设计者来定义给定数据库中将要使用的条件名以及每个条件名的含义。

通常,通知条件名与数据库中某张表的名称相同,通知事件本质上意味着"我改动了这张表,看看它有什么新内容"。但 NOTIFY 和 LISTEN 命令并不强制这种关联。例如,数据库设计者可以用几个不同的条件名来表示对单个表不同种类的更改。

NOTIFY 为访问同一 Postgres 数据库的一组进程提供了一种简单的信号或 IPC(进程间通信)机制。通过使用数据库中的表,可以构建从通知者向监听者传递附加数据(而不仅仅是条件名)的更高层机制。

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

NOTIFY 在若干重要方面与 SQL 事务交互。首先,如果在事务内部执行了 NOTIFY,通知事件直到且仅当事务提交时才会被送达。这是恰当的,因为如果事务中止,我们希望其中的所有命令都不产生效果,包括 NOTIFY。但如果期望通知事件立即送达,这可能会让人不安。其次,如果一个正在监听的后端在处于事务中时收到一个通知信号,该通知事件要到事务刚完成(提交或中止)之后才会送达其连接的前端。同样,其理由是:如果一个通知在某个后来被中止的事务内被送达,人们会希望以某种方式撤销该通知——但后端一旦把通知发给了前端,就无法"收回"它。因此通知事件只在事务之间送达。由此得出的结论是:使用 NOTIFY 进行实时信号传递的应用应尽量保持事务简短。

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

发送 NOTIFY 的前端自己同时也在监听同一通知名,这是很常见的情形。在这种情况下,它会像其他所有监听前端一样收到一个通知事件。根据应用逻辑,这可能导致无用功——例如再次读取数据库表,找到的却正是该前端自己刚刚写入的更新。在 Postgres 6.4 及之后的版本中,可以通过检查发出通知的后端进程的 PID(在通知事件消息中提供)是否与自己的后端的 PID(可从 libpq 获得)相同来避免这种额外工作。二者相同时,该通知事件就是自己发的工作回弹回来,可以忽略。(尽管前一段有那样的说法,但这是一种安全的技术。Postgres会把自身通知与来自其他后端的通知分开保存,因此忽略自己的通知并不会让你错过来自外部的通知。)

注意

name 可以是任何作为名称有效的字符串;它不必对应任何实际表的名称。如果 name 用双引号括起,它甚至不必是语法上有效的名称,而可以是长度最多 31 个字符的任意字符串。

在 Postgres 的一些早期版本中,当 name 不对应任何现有表名时,即使语法上是有效的名称,也必须用双引号括起。这一要求已不再存在。

在 6.4 之前的 Postgres 版本中,通知消息中传递的后端 PID 总是前端自己的后端的 PID。因此在那些早期版本中,无法把自己的通知与其他客户的通知区分开。

用法

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

LISTEN virtual;
NOTIFY virtual;
Asynchronous NOTIFY 'virtual' from backend with pid '8448' received. 

兼容性

SQL92

SQL92 中没有 NOTIFY 语句。

提交更正

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