NOTIFY

Name

NOTIFY  -- 通知の生成

Synopsis

NOTIFY name        
  

入力

notifyname

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

出力

NOTIFY

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

Notify events

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

説明

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

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

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

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

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

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

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

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

注釈

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

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

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

使用方法

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

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

互換性

SQL92

SQL92 には NOTIFY はありません。