?
本文檔使用 PHP中文網(wǎng)手冊 發(fā)布
NOTIFY channel [ , payload ]
NOTIFY命令發(fā)送一個通知事件連同一個可選擇的"payload" 字符串到每個客戶端應用程序,這些應用程序已經預先為當前數(shù)據(jù)庫的指定通道名稱執(zhí)行 LISTEN channel。
NOTIFY提供了一個訪問相同PostgreSQL 數(shù)據(jù)庫的進程集的單一進程間通信機制。一個有效負載字符串可以連同通知一起發(fā)送, 高級機制通過結構化數(shù)據(jù)可以通過使用數(shù)據(jù)庫中的表來建立,來講通知器的額外數(shù)據(jù)傳遞給監(jiān)聽器。
為通知事件傳遞給客戶端的信息包括通知通道名稱,通知會話的服務器進程PID, 和負載字符串,若它未被指定則是空字符串。
定義用于給定數(shù)據(jù)庫的通道名稱以及每個名稱的含義由數(shù)據(jù)庫的設計者決定。通常, 通道名與數(shù)據(jù)庫中的一些表相同,以及通知時間的本質含義,"我更改該表, 看看什么是新的"。但是NOTIFY和LISTEN 不強制此類關聯(lián)規(guī)則。例如,一個數(shù)據(jù)庫設計者可以使用幾個不同的通道名稱來標記 對一個單一變的不同種類的更改?;蛘撸行ж撦d字符串可以用來區(qū)分不同的情況。
當NOTIFY用于通知某一特定表修改的動作的發(fā)生,一個實用的編程 技巧是將NOTIFY放在一個由表更新觸發(fā)的規(guī)則里。用這種方法,通 知將在表更新的時候自動觸發(fā),而且應用程序員不會碰巧忘記處理它。
NOTIFY和SQL事務用某種重要的方法進行交換。首先,如果 NOTIFY在事務內部執(zhí)行,通知事件直到事務提交才會送出。 這么做是有道理的,因為如果事務退出了,那么在它里面的所有命令都沒有效果 (包括NOTIFY)。但如果有人希望通知事件立即發(fā)送,這就不太好了。 其次,當一個正在監(jiān)聽的會話在一次事務內收到一個通知信號,直到本次事務完成(提交或退出) 之前,該通知事件將不被送到與之相連的客戶端。同樣,如果一個通知在事務內部發(fā)送出去了, 而該事務稍后又退出了,就希望通知可以在某種程度上被撤消,因為通知一旦發(fā)送出去,服務器 便不能從客戶端"收回"通知,所以通知時間只是在事務之間傳遞。這一點就要求 使用NOTIFY作為實時信號的應用應該確保他們的事務盡可能短。
若相同的通道名稱多次從具有相同負載字符串的相同事務中多次提示,數(shù)據(jù)庫服務器僅可以決定 發(fā)送一個單一通知。另一方面,有不同的有效負載的字符串的通知總是被交付作為不同的通知。 類似地,來自不同事務的通知從不能合到一個通知中。除了不刪除稅后的重復通知實例, NOTIFY保證來自相同事務的通知會按照他們發(fā)送時的順序交付。這也保證了 來自不同事務的信息會按照事務提交的順序交付。
對于一個客戶來說執(zhí)行監(jiān)聽相同通知通道本身的NOTIFY事很正常的。 在這種情況下將返回一個通知事件,就像所有其他的監(jiān)聽會話。根據(jù)應用程序邏輯,這回導致 無效的工作,例如:讀取一個數(shù)據(jù)庫表來找出會話剛寫出的相同更新。可以通過注意該通知會話 的服務器進程PID(通知時間信息中提供的)來避免此類服務器進程,該進程 PID與其會話的相同(libpq中可獲得的)。當他們相同時,通知 事件是其本身反彈回來的工作。
要表示的通知通道的名稱 (任意標示符)。
與通知交互的"payload"字符串。這必須被指定為一個簡單的字符串。 在默認配置中它必須小于8000字節(jié)。(若二進制數(shù)據(jù)或者更大數(shù)量的信息需要被聯(lián)系起來。 最好是將它們放到一個數(shù)據(jù)庫中并發(fā)送記錄的關鍵。)
有一個隊列,它持有被發(fā)送但是卻未被所有監(jiān)聽會話處理的通知。若果該隊列變?yōu)榭眨聞照{用 NOTIFY將會提交失敗。隊列很大(在標準安裝中是8GB)并且應該對幾乎所 有用例有充足的空間。然而,若一個會話執(zhí)行LISTEN并隨后很長時間輸入事務 那么不會發(fā)生清理。此時您應該確定該會話結束其當前事務,這樣清理就可以進行。
執(zhí)行過NOTIFY的事務無法準備兩階段提交。
為了發(fā)送一個提示你也可以使用函數(shù) pg_notify
(text,
text)。該函數(shù)將通道明名稱作為首個參數(shù),并且將有效負載作為第二個。
該函數(shù)比NOTIFY命令更好用,如果您需要運轉不恒定通道名稱和有效載荷。
在psql里配置和執(zhí)行一個監(jiān)聽/通知對:
LISTEN virtual; NOTIFY virtual; Asynchronous notification "virtual" received from server process with PID 8448. NOTIFY virtual, 'This is the payload'; Asynchronous notification "virtual" with payload "This is the payload" received from server process with PID 8448. LISTEN foo; SELECT pg_notify('fo' || 'o', 'pay' || 'load'); Asynchronous notification "foo" with payload "payload" received from server process with PID 14728.
SQL標準里沒有NOTIFY語句。