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