PostgreSQL 異步提示

2021-09-02 11:30 更新

PostgreSQL通過LISTENNOTIFY命令提供了異步通知。一個(gè)客戶端會(huì)話用LISTEN命令在一個(gè)特定的通知頻道中注冊(cè)它感興趣的通知(也可以用UNLISTEN命令停止監(jiān)聽)。當(dāng)任何會(huì)話執(zhí)行一個(gè)帶有特定頻道名的 NOTIFY命令時(shí),所有正在監(jiān)聽該頻道的會(huì)話會(huì)被異步通知。可以傳遞一個(gè)載荷字符串來與監(jiān)聽者溝通附加的數(shù)據(jù)。

libpq應(yīng)用把LISTENUNLISTENNOTIFY命令作為通常的 SQL 命令提交。 隨后通過調(diào)用PQnotifies. 來檢測(cè)NOTIFY消息的到達(dá)。

函數(shù)PQnotifies從來自服務(wù)器的未處理通知消息列表中返回下一個(gè)通知。如果沒有待處理的信息則返回一個(gè)空指針。一旦PQnotifies返回一個(gè)通知,該通知會(huì)被認(rèn)為已處理并且將被從通知列表中刪除。

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對(duì)象后,別忘了用PQfreemem把它釋放。 釋放PGnotify指針就足夠了; relnameextra域并不代表獨(dú)立分配的內(nèi)存(這些域的名稱是歷史性的,尤其是頻道名稱與關(guān)系名稱沒有什么聯(lián)系)。

例 33.2給出了一個(gè)例子程序展示異步通知的使用。

PQnotifies實(shí)際上并不從服務(wù)器讀取數(shù)據(jù);它只是返回被另一個(gè)libpq函數(shù)之前吸收的消息。 在以前的libpq版本中,及時(shí)收到NOTIFY消息的唯一方法是持續(xù)地提交命令,即使是空命令也可以,并且在每次 PQexec 后檢查PQnotifies。 雖然這個(gè)方法還能用,但是由于太過浪費(fèi)處理能力已被廢棄。

當(dāng)你沒有可用的命令提交時(shí),一種更好的檢查NOTIFY消息的方法是調(diào)用PQconsumeInput ,然后檢查PQnotifies。 你可以使用select()來等待服務(wù)器數(shù)據(jù)到達(dá),這樣在無事可做時(shí)可以不浪費(fèi)CPU能力(參考PQsocket來獲得用于 select()的文件描述符)。 注意不管是用PQsendQuery/PQgetResult提交命令還是簡(jiǎn)單地使用 PQexec ,這種方法都能正常工作。 不過,你應(yīng)該記住在每次PQgetResultPQexec之后檢查PQnotifies,看看在命令的處理過程中是否有通知到達(dá)。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)