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
語句。
如果您在文件中看到任何不正確的內容、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用 此表單 報告文件問題。