非同期通知

PostgreSQL 8.4.1文書
前のページ | 巻戻し | 第 30章libpq - C ライブラリ | 早送り | 次のページ

# 30.7. 非同期通知

PostgreSQLは、`LISTEN`と`NOTIFY`コマンドを使用した、非同期通知をサポートします。 クライアントセッションは、`LISTEN`コマンドを使用して処理対象とする特定の通知条件を登録します。 (通知監視を取り止めるには`UNLISTEN`コマンドを使用します。) 任意のセッションでその条件名による`NOTIFY`コマンドが実行されると、特定条件を監視している全てのセッションは非同期に通知を受け取ります。 通知元から通知先へはこれ以上の情報は渡されません。 従って、通常通信しなければならない実際のデータはデータベーステーブルを介して転送されます。 一般的に、条件名は関連するリレーション名と同じものですが、必ず関連するリレーションが必要とされるわけではありません。

libpqアプリケーションは、通常のSQLによる問い合わせと同じように`LISTEN`と`UNLISTEN`コマンドを発行することができます。 `NOTIFY`メッセージの到着は、続いて`PQnotifies`を呼び出せば検出できます。

`PQnotifies`は、サーバから受信した通知メッセージの未処理リストから次の通知を返します。 保留中の通知がなくなれば NULLポインタを返します。 `PQnotifies` が通知を返すと、その通知は処理済みとみなされ、通知リストから取り除かれます。

       PGnotify *PQnotifies(PGconn *conn);

       typedef struct pgNotify {
        char *relname;              /* 通知条件名 */
        int  be_pid;                /* 通知元サーバプロセスのプロセスID */
        char *extra;                /* 通知パラメータ */
       } PGnotify;

`PQnotifies`で返された`PGnotify`オブジェクトの処理が終わったら、`PQfreemem`を使用して確実に解放してください。 `PGnotify` ポインタを解放することは重要です。 `relname`と`extra`フィールドは別の割り当てを表していません。 (現在、`extra`フィールドは使用されておらず、常に空文字列へのポインタとなります。)

例30-2で、非同期通知を使用したサンプルプログラムを示しています。

`PQnotifies()`は実際にサーバのデータを読み出すわけではありません。 これは単に、他のlibpq関数が吸収してしまっていた通知メッセージを返すだけです。 libpqの以前のリリースでは、通知メッセージを適切な時点で確実に受け取るには、空の問い合わせでも何でも、とにかく一定時間ごとに問い合わせを送り、そして`PQexec()`を実行するたびに`PQnotifies()`をチェックするしかありませんでした。 今でもこの方法は動作しますが、処理能力の無駄使いをすることになるのでやめておくべきでしょう。

実行すべき問い合わせがない時に通知メッセージをチェックするよい方法は、まず`PQconsumeInput()`を呼び出し、それから`PQnotifies()`をチェックすることです。 サーバからのデータの到着を`select()`で待つことができ、不必要な動作でCPUパワーを消費してしまうことがありません （`select()`で使用するファイル記述子番号の取得については、`PQsocket()`を参照してください）。 なお、これは問い合わせに`PQsendQuery`と`PQgetResult`を使った時でも、またはおなじみの`PQexec`を使った時でも動作します。 しかし通知がコマンドの処理中に届いていないかどうか、`PQgetResult`あるいは`PQexec`の実行ごとに`PQnotifies()`を調べることを忘れないようにしておくべきです。

前のページ | ホーム | 次のページ
近道インタフェース | 上に戻る | `COPY`コマンド関連関数