NOTIFY — 產生通知
NOTIFYchannel
[ ,payload
]
NOTIFY
命令會將通知事件與一個可選的 “酬載” 字串傳送給先前在目前資料庫中,對指定的頻道名稱執行過 LISTEN
的每個用戶端應用程式。通知對所有使用者都是可見的。channel
NOTIFY
提供了一個簡單的程序間通訊機制,供存取相同 PostgreSQL 資料庫的一組程序使用。一個酬載字串可以與通知一起傳送,並且可以透過使用資料庫中的表格來傳送額外的資料,從通知者到監聽者,來建立更高層次的機制來傳遞結構化資料。
傳遞給客戶端的通知事件資訊包括通知頻道名稱、發送通知的伺服器程序PID以及酬載字串,如果沒有指定酬載字串,則為空字串。
由資料庫設計者來定義在給定的資料庫中將使用的頻道名稱以及每個名稱的意義。通常,頻道名稱與資料庫中某個表格的名稱相同,並且通知事件本質上意味著,“我更改了這個表格,請查看它以了解有哪些新的內容”。但是,NOTIFY
和 LISTEN
命令沒有強制執行這種關聯。例如,資料庫設計者可以使用幾個不同的頻道名稱來表示對單個表格的不同種類的變更。或者,可以使用酬載字串來區分各種情況。
當 NOTIFY
用於指示特定表格發生變更時,一種有用的程式設計技術是將 NOTIFY
放入由表格更新觸發的陳述式觸發程序中。這樣,當表格變更時,通知會自動發生,並且應用程式設計師不會意外忘記執行它。
NOTIFY
以一些重要的方式與 SQL 交易互動。首先,如果在交易內部執行 NOTIFY
,則通知事件要等到交易提交時才會傳遞。這是適當的,因為如果交易中止,則其中的所有命令都無效,包括 NOTIFY
。但是,如果有人期望通知事件立即傳遞,則可能會感到不安。其次,如果監聽會話在其位於交易中時收到通知信號,則直到交易完成(提交或中止)後才會將通知事件傳遞到其連線的客戶端。同樣,原因是如果在稍後中止的交易中傳遞了通知,則會希望以某種方式撤銷該通知 — 但是伺服器無法在將通知傳送給客戶端後 “收回” 通知。因此,通知事件僅在交易之間傳遞。這樣做的結果是,使用 NOTIFY
進行即時信號傳輸的應用程式應盡量縮短其交易。
如果在同一交易中多次發出具有相同酬載字串的相同頻道名稱信號,則只會將通知事件的一個實例傳遞給監聽者。另一方面,具有不同酬載字串的通知將始終作為不同的通知傳遞。同樣,來自不同交易的通知永遠不會合併為一個通知。除了捨棄稍後的重複通知實例之外,NOTIFY
保證來自同一交易的通知會按照傳送的順序傳遞。它也保證來自不同交易的訊息會按照交易提交的順序傳遞。
執行 NOTIFY
的客戶端通常會在同一通知頻道上進行監聽。在這種情況下,它會像所有其他監聽會話一樣收到通知事件。根據應用程式邏輯,這可能會導致無用的工作,例如,讀取資料庫表格以尋找該會話剛寫出的相同更新。可以透過注意發送通知的伺服器程序來避免這種額外的工作PID(在通知事件訊息中提供)是否與您自己會話的相同PID(可從 libpq 獲得)。當它們相同時,通知事件就是您自己的工作反彈回來,可以忽略。
頻道 (channel)
要發出信號的通知頻道名稱(任何識別碼)。
酬載 (payload)
與通知一起傳達的 “酬載” 字串。這必須指定為簡單的字串文字。在預設設定中,它必須小於 8000 位元組。(如果需要傳達二進位資料或大量資訊,最好將其放入資料庫表格中並傳送記錄的鍵。)
有一個佇列用於保存已發送但尚未被所有監聽會話處理的通知。如果這個佇列已滿,呼叫 NOTIFY
的交易會在提交時失敗。這個佇列相當大(在標準安裝中為 8GB),應該足以應付幾乎所有使用情境。然而,如果一個會話執行 LISTEN
然後長時間進入交易,則無法進行清理。一旦佇列達到一半滿,您會在日誌檔中看到警告,指出阻止清理的會話。在這種情況下,您應該確保該會話結束其當前交易,以便可以進行清理。
函數 pg_notification_queue_usage
返回當前被待處理通知佔用的佇列比例。 更多資訊請參閱 第 9.27 節。
已執行 NOTIFY
的交易無法準備用於兩階段提交。
從 psql 配置和執行一個監聽/通知序列
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
語句。
如果您在文件中發現任何不正確、與您特定功能的經驗不符或需要進一步澄清的地方,請使用此表格報告文件問題。