NOTIFY

Name

NOTIFY  --  ある通知条件を監視する全てのフロントエンド、バックエンドに信号 を送る。

Synopsis

NOTIFY name        
  

入力

notifyname

信号が送られる通知条件。

出力

NOTIFY

notify コマンドが実行された証明。

Notify events

イベントが監視しているフロントエンドに配送されたことを示し ます。フロントエンドアプリケーションがイベントに対して反応 するかどうか、反応するとしたらどのように反応するのかはその プログラミングに依存します。

説明

NOTIFY コマンドは、現在のデータベース内で指定通 知条件に対して LISTEN notifyname を事前に実行していた各フロントエンドアプリケーションに通知イベント を送ります。

通知イベントとしてフロントエンドに渡される情報には、通知条件名と通 知を行なうバックエンドプロセスの PID が含まれます。与えられたデー タベースにおいて使用される条件名とそれが何を意味するのかに関する定 義はデータベース設計者に任されています。

一般には、通知条件名はデータベースにあるどこかのテーブルの名前と同 じものであり、通知イベントは基本的には「私はこのテーブルを変更しまし た。何が新しくなったかについて注目して下さい」を意味するものです。 しかし、NOTIFYLISTEN コマ ンドでは、そのような関連付けは強制されていません。例えば、データベ ース設計者は一つのテーブルへの異なった種類の変更を知らせるために、 いくつかの異なった条件名を使用することができます。

NOTIFY はシグナルの単純な形式、または、同一の Postgres データベースにアクセスするプロセ スを収集する IPC(プロセス内通信)機構を備えています。通知者からリ スナ(複数可)に追加的な(単なる条件名を越えた)データを渡すためのデ ータベース内のテーブルを使用することで、より高レベルの機構を構築する ことができます。

NOTIFY を特定のテーブルへの変更の発生を知らせる ために使用する場合に有用なプログラム開発テクニックは、 NOTIFY をテーブル更新時に発行されるルール内にお くことです。この方法では通知はテーブルが変更された時に自動的に行な われますので、アプリケーションプログラマが通知の実行を忘れるといっ た事故を防ぐことができます。

NOTIFY と SQL トランザクションの間にはいくつか重 要な相互作用があります。まず、NOTIFYがトランザク ション内部で実行された場合、通知イベントはトランザクションがコミット されるまで、そして、コミットされない限り配送されません。トランザクシ ョンがアボートしたならば、NOTIFY を含む、トランザ クション内で行なわれた全てのコマンドが何の影響も及ぼさないようにする という点から、このことは適切といえます。しかし、もしも通知イベントが 即座に配送されることを期待していたとすると、このことは不安になること があります。次に、監視中のバックエンドがトランザクション処理中に通知 信号を受け取った場合、通知イベントはそのトランザクションが(コミット されるかアボートされるかのどちらかによって)完了するまで、バックエン ドに接続したフロントエンドに配送されません。この理由は繰り返しになり ますが、通知がトランザクション内から配送され、その後にトランザクショ ンがアボートしたとすると、その通知も何とか取り消したくなりますが、し かし、バックエンドは一旦フロントエンドに送信した通知を「取り戻す」こ とができないということです。ですので、通知イベントはトランザクション とトランザクションの合間にのみ配送されます。この結果、実時間レベルで の信号処理のために NOTIFY を使用するアプリケーショ ンではそのトランザクション処理を短くしておかなければなりません。

NOTIFY は次の重要な点において Unix のシグナルと 似た動作を行ないます。同一の条件名が短期間に連続して複数回発せられ た場合、複数の NOTIFY の実行に対して、受信者は 1 つの通知イベントのみしか受け取らない場合があります。ですので、通 知を受信した回数に依存することは良くない考え方となります。それより も、何かに注意をしなければならないアプリケーションを起動させる場合 に NOTIFY を使用して下さい。そして、何が起こった のかを追跡したり、何回起こったのかを数えたりする場合には、(シーケ ンスなどの) データベースオブジェクトを使って下さい。

NOTIFY を送るフロントエンドが、その同じ通知名を自 分自身が監視していることは良くあることです。この場合、他のすべての監 視を行なっているフロントエンドと全く同様に通知イベントが戻ってきます。 アプリケーションのロジックに依存しますが、これは無用な作業を行なう結 果になることがあります。例えば、フロントエンドが書き出したばかりの更新 そのものを検索するためのデータベースのテーブルの再読み込みです。 Postgres の 6.4 以降では、(通知イベントメ ッセージ内にある) 通知を行なったバックエンドプロセスの PID と( libpq によって入手できる) 自身のバックエンドの PID が同じかどうかに注 意することで、こういった余計な作業を防止することができます。もし同じで あれば、通知イベントは自分自身から跳ね返ってきたものであり、無視するこ とができます。(前の段落で説明したことと反しますが、これは安全なテクニ ックです。Postgres は他のバックエンドからの 通知と自身からの通知を別々に保持しますので、自分自身の通知を無視したと しても外部からの通知をとり逃すことは起こり得ません。)

注意

nameは、名前としてど んな文字列でもかまいません。実テーブルの名前に対応させる必要は全く ありません。name が二 重引用符で括られていた場合は、文法的に有効なものである必要すら ありません。しかし、その長さには 31 文字までの任意の文字列という制限 があります。

以前の Postgres のリリースには、 name が文法的には有 効であっても既存のテーブル名に対応していない場合は二重引用符 で括らなければならないものもありました。これは現在は不要です。

6.4 以前のリリースの Postgres では、 通知メッセージ内で配送されるバックエンドの PID は常にフロントエ ンド自身に対応したバックエンドの PID でした。ですので、これらの 古いリリースでは自身からの通知と他のクライアントの通知を区別する ことはできませんでした。

使用法

psqlから監視/通知処理の設定と実行 を行なう。

=> LISTEN virtual;
=> NOTIFY virtual;
Asynchronous NOTIFY 'virtual' from backend with pid '8448' received. 

互換性

SQL92

SQL92 にはNOTIFY 文はあ りません。