2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本: devel
不支援的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

32.9. 非同步通知 #

PostgreSQL 透過 LISTENNOTIFY 命令提供非同步通知。客戶端會話使用 LISTEN 命令註冊其對特定通知頻道的興趣(並可以使用 UNLISTEN 命令停止監聽)。當任何會話執行帶有特定頻道名稱的 NOTIFY 命令時,所有在該頻道上監聽的會話都將收到非同步通知。可以透過 payload 字串來傳遞附加資料給監聽者。

libpq 應用程式將 LISTENUNLISTENNOTIFY 命令作為普通 SQL 命令提交。稍後可以透過呼叫 PQnotifies 來檢測到 NOTIFY 訊息的到達。

函式 PQnotifies 返回從伺服器接收到的未處理通知訊息列表中的下一個通知。如果沒有待處理通知,則返回一個空指標。一旦從 PQnotifies 返回一個通知,它就被視為已處理,並將從通知列表中移除。

PGnotify *PQnotifies(PGconn *conn);

typedef struct pgNotify
{
    char *relname;              /* notification channel name */
    int  be_pid;                /* process ID of notifying server process */
    char *extra;                /* notification payload string */
} PGnotify;

在處理由 PQnotifies 返回的 PGnotify 物件後,請務必使用 PQfreemem 來釋放它。釋放 PGnotify 指標就足夠了;relnameextra 欄位不代表單獨的分配。(這些欄位的名稱是歷史遺留的;特別是,頻道名稱不一定與關係名稱有關。)

示例 32.2 提供了一個演示非同步通知用法的示例程式。

PQnotifies 實際上並不從伺服器讀取資料;它只是返回之前由另一個 libpq 函式吸收的訊息。在 libpq 的早期版本中,確保及時接收 NOTIFY 訊息的唯一方法是不斷提交命令,即使是空的命令,然後在每次 PQexec 呼叫後檢查 PQnotifies。雖然這仍然有效,但由於浪費了處理能力,因此已被棄用。

當沒有有用的命令要執行時,檢查 NOTIFY 訊息的更好方法是呼叫 PQconsumeInput ,然後檢查 PQnotifies。您可以使用 select() 來等待伺服器上的資料到達,從而不使用CPU資源,除非有事情要做。(要獲取與 select() 一起使用的檔案描述符編號,請參見 PQsocket。)請注意,無論您是使用 PQsendQuery/PQgetResult 提交命令還是僅使用 PQexec,這都可以正常工作。但是,您應該記住在每次 PQgetResultPQexec 呼叫後檢查 PQnotifies,以檢視在處理命令期間是否收到了任何通知。

提交更正

如果您在文件中發現任何不正確之處、與您對特定功能的實際體驗不符或需要進一步澄清的內容,請使用 此表單 報告文件問題。