PostgreSQL7.0手冊-用戶手冊-19. SQL命令-NOTIFY
2019-09-08 23:33:42
供稿:網友
NOTIFY
名稱
NOTIFY ― 通知所有正在監聽某個通知條件的前端和后端
語法
NOTIFY name
輸入
notifyname
生成信號(通知)的通知條件.
輸出
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?。ㄔ谕ㄖ录刑峁┦欠衽c自己的后端的 PID 一致(從libpq中取得).當他們一樣時,說明這是其自身回彈的信息,可以忽略.(不管前面章節是如何講的,這是一個安全的技巧.Postgres 保持自身的通知和其他到來的通知區分開.所以你屏蔽了自己的通知后不會略過外部的通知.)
注意
name 可以是作為名稱的任何字串;它不需要與任何實際的表的名稱對應.如果用雙引號將 name 括起,它甚至可以不是語法上有效的名稱,可以是任何小于31字符長的字串.
在以前的 Postgres 版本,name 如果和不和任何現存的表名對應時必須用雙引號引起來,即使它在語法上是正確的也這樣?,F在不需要這樣做了?!?
Postgres 早于 6.4 的版本,在通知信息送出的后端 PID 總是前端自己的后端的 PID.所以在那些早期版本里,不可能將自身的通知信息和別的客戶端的通知信息區分開.
用法
在psql 里配置和執行一個監聽/通知對:
=> LISTEN virtual;
=> NOTIFY virtual;
Asynchronous NOTIFY 'virtual' from backend with pid '8448' received.
兼容性
SQL92
在 SQL92 里沒有 NOTIFY 語句.