NOTIFY コマンドは、現在のデータベース内で指定通 知条件に対して LISTEN notifyname を事前に実行していた各フロント エンドアプリケーションに通知イベントを送ります。
通知イベントとしてフロントエンドに渡される情報には、通知条件名と 通知を行なうバックエンドプロセスの PID が含まれます。与えられた データベースにおいて使用される条件名とそれが何を意味するのかに関する 定義はデータベース設計者に任されています。
一般には、通知条件名はデータベースにあるどこかのテーブルの名前と同 じものであり、通知イベントは基本的には「私はこのテーブルを変更まし た。何が新しくなったかについて注目して下さい」ということを意味 するものです。 しかし、NOTIFY と LISTEN コマンドでは、そのような関連付けは強制 されていません。例えば、データベース設計者は一つのテーブルへの 異なった種類の変更を知らせるために、いくつかの異なった条件名を 使用することができます。
NOTIFY はシグナルの単純な形式、または、同一の Postgres データベースにアクセスする プロセスを収集する IPC(プロセス内通信)機構を備えています。通知者 からリスナ(複数可)に追加的な(単なる条件名を越えた)データを 渡すためのデータベース内のテーブルを使用することで、より高レベルの機 構を構築することができます。
NOTIFY を特定のテーブルへの変更の発生を知らせる ために使用する場合に有用なプログラム開発テクニックは、 NOTIFY をテーブル更新時に発行されるルール内 におくことです。この方法では通知はテーブルが変更された時に自動的 に行なわれますので、アプリケーションプログラマが通知の実行を忘れる といった事故を防ぐことができます。
NOTIFY interacts with SQL transactions in some important ways. Firstly, if a NOTIFY is executed inside a transaction, the notify events are not delivered until and unless the transaction is committed. This is appropriate, since if the transaction is aborted we would like all the commands within it to have had no effect, including NOTIFY. But it can be disconcerting if one is expecting the notify events to be delivered immediately. Secondly, if a listening backend receives a notify signal while it is within a transaction, the notify event will not be delivered to its connected frontend until just after the transaction is completed (either committed or aborted). Again, the reasoning is that if a notify were delivered within a transaction that was later aborted, one would want the notification to be undone somehow___but the backend cannot "take back" a notify once it has sent it to the frontend. So notify events are only delivered between transactions. The upshot of this is that applications using NOTIFY for real-time signaling should try to keep their transactions short. --> 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 でした。ですので、これらの 古いリリースでは自身からの通知と他のクライアントの通知を区別する ことはできませんでした。