Postgresは LISTEN と NOTIFY コマンドによる 非同期通知機能をサポートしています。バックエンドは LISTEN コマンドを受 け取ると、特定の通知条件に関心を持ったことを登録します。(これを止める には UNLISTEN コマンドを使います) 特定の条件を待っているすべてのバックエンドは、同じ条件名の NOTIFY コマ ンドが任意のバックエンドによって実行された時点で非同期的に通知を受けま す。 ただし通知の発行側から受信側へ渡される付加的な情報はありません。したがっ て、典型的には両者の間で受け渡す必要のある実際のデータは、データベース リレーションを通じて転送することになります。一般的に、条件名は関連する リレーション名と同じものですが、必ず関連するリレーションが必要とされる わけではありません。
libpqアプリケーションは、通常の SQL による問い合 わせと同じように LISTEN および UNLISTEN コマンドを発行することができま す。通知メッセージの到着は、続いて PQnotifies() を呼び出せば検出できま す。
PQnotifies バックエンドから受信した通知メッセージのうち、まだ処理されて いないもののリストから次の通知を返します。保留中の通知がなく なれば NULL を返します。PQnotifies が通知を返すとその通知は もはや処理が済んだものとみなされ、通知リストから取り除かれま す。
PGnotify* PQnotifies(PGconn *conn); typedef struct pgNotify { char relname[NAMEDATALEN]; /* データを含むリレーションの名前 */ int be_pid; /* バックエンドのプロセスID */ } PGnotify;メモリリークを防ぐため、PQnotifiesが返した PGnotifyオブジェクトの処理が終わったら、必ず free()で領域を解放してください。
Note: 6.4 より前のバージョンでは、be_pid が常に接続してい るバックエンドのプロセス ID だったのに対し、6.4 とそれ以降の Postgres では通知を発行したバックエンドの プロセス ID になります。
二つめのサンプルプログラムは、非同期通知の使い方の一例です。
PQnotifies()は実際にバックエンドのデータを読み出 すわけではありません。これは単に、他のlibpq 関数が吸収してしまっていた通知メッセージを返すだけです。以前のリリース のだと、通知メッセージを適切な時点で確実に受け取るには、空の問い合わせ でもなんでも、とにかく一定時間ごとに問い合わせを送り、そして PQexec()を実行する度に PQnotifies()をチェックするしかありませんでした。 今でもこの方法は動作しますが、処理能力の無駄使いをすることになるのでや めておいてください。
実行するべき問い合わせがないときに通知メッセージをチェックするよい方法 は、まずPQconsumeInput()を呼び出し、それから PQnotifies()をチェックすることです。 バックエンドからのデータの到着を select(2) で待つ ことができ、不必要な動作で CPU パワーを消費してしま うことがありません。(selectで使用するファイル識別 子番号の取得については、PQsocket()を参照してくだ さい。) なお、これは問い合わせにPQsendQueryと PQgetResultを使ったときでも、またはおなじみの PQexecを使ったときでも動作します。 しかし通知が問い合わせの処理中に届いていないかどうか、 PQgetResultあるいはPQexecの 実行毎にPQnotifies()を調べることを忘れないように しておくべきです。