NOTIFY

Name

NOTIFY  --  生成一个通知

Synopsis

NOTIFY name        
  

输入

notifyname

生成信号(通知)的通知条件.

输出

NOTIFY

确认通知命令已经执行了.

Notify events

事件发送给在监听的前端;前端是否响应或怎样响应取决于它自身的程序.

描述

NOTIFY 命令向当前数据库中所有执行过 LISTEN notifyname ,正在监听特定通知条件的前端应用发送一个通知事件.

传递给前端的通知事件包括通知条件名和发出通知的后端进程PID. 数据库设计者有责任定义用于某个数据库的条件名和每个通知条件的含义.

通常,通知条件名与数据库里的表的名字相同, 通知时间实际上意味着"我修改了此数据库,请看一眼有什么新东西". NOTIFYLISTEN 命令并不强制这种联系.例如, 数据库设计者可以使用几个不同的条件名来标志一个表的几种不同改变.

NOTIFY 为访问 PostgreSQL 数据库的一组进程提供了一种简单的信号形式或IPC(进程间通讯)机制. 更高级的机制可以通过使用数据库中的表从通知者传递数据到被通知者.

NOTIFY用于通知某一特定表修改的动作的发生, 一个实用的编程技巧是将 NOTIFY 放在一个由表更新触发的规则里.用这种方法, 通知将在表更新的时候自动触发,而且应用程序员不会碰巧忘记处理它.

NOTIFY 和 SQL 事务用某种重要的方法进行交换.首先,如果 NOTIFY 在事务内部执行,通知事件直到事务提交才会送出. 这么做是有道理的,因为如果事务退出了, 我们将希望在它里面的所有命令都没有效果 - 包括 NOTIFY.但如果有人希望通知事件及时发送,这 就不太好了.其次,当一个正在监听的后端在一次事务内收到一个通知信号, 直到本次事务完成(提交或退出)之前,该通知事件将不被 送到与之相连的前端。同样,如果一个通知在事务内部发送出去了, 而该事务稍后又退出了,我们就希望通知可以在某种程度上被撤消- -但通知一旦发送出去,后端便不能从前端"收回" 通知. 所以通知时间只是在事务之间传递.这一点就要求使用 NOTIFY 作为实时信号的 应用应该确保他们的事务尽可能短.

NOTIFY 在一方面的行为象 Unix 的信号: 如果同一条件名在短时间内发出了多条信号,接收者几次执行 NOTIFY 可能只回收到一条通知信息. 所以依赖于收到的通知条数的方法是很不可靠的.因而,使用 NOTIFY唤醒需要关注某事的应用, 同时还要使用数据库对象(如序列号)来跟踪事件发生了几次.

前端经常会自己发送与正在监听的通知名一样的 NOTIFY . 这时它(前端)也和其他正在监听的前端一样收到一个通知事件.这样可能导 致一些无用的工作(与应用逻辑有关)-- 例如, 对前端刚写过的表又进行一次读操作以发现是否有更新.在 PostgreSQL 6.4 更新的版本 中,我们可以通过检查后端进程的PID(在通知事件中提供) 是否与自己的后端的PID一致(从libpq中取得).当他们一样时,说明这 是其自身回弹的信息,可以忽略.(不管前面章节是如何讲的, 这是一个安全的技巧. PostgreSQL 保持自身的通知和其他到来的通知区分 开.所以你屏蔽了自己的通知后不会略过外部的通知.)

注意

name 可以是作为名称的任何字串;它不需要与任何实际的表的名称对应. 如果用双引号将 name 括起,它甚至可以不是语法上有效的名称,可以是任何小于63字符长的字串.

在以前的 PostgreSQL 版本, name 如果和不和任何现存的表名对应时必须用双引号引起来, 即使它在语法上是正确的也这样。现在不需要这样做了。

PostgreSQL 早于 6.4 的版本, 在通知信息送出的后端PID总是前端自己的后端的PID. 所以在那些早期版本里, 不可能将自身的通知信息和别的客户端的通知信息区分开.

用法

psql 里配置和执行一个监听/通知对:

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

兼容性

SQL92

SQL92 里没有 NOTIFY语句.