NOTIFY コマンドは、現在のデータベース内で指定通知条件に対して LISTEN notifyname を事前に実行していた各クライアントアプリケーションに通知イベントを送ります。
通知イベントとしてクライアントに渡される情報には、通知条件名と通知を行なうサーバプロセスの PID が含まれます。 与えられたデータベースにおいて使用される条件名とそれが何を意味するのかに関する定義はデータベース設計者に任されています。
一般には、通知条件名はデータベース内にあるテーブルの名前と同じもので、通知イベントは基本的に"私はこのテーブルを変更しました。変更された箇所を確認してください"ということを意味するものです。 しかし、NOTIFY と LISTEN コマンドでは、そのような関連付けは強制されていません。 例えば、データベース設計者は一つのテーブルへの異なった種類の変更を知らせるために、複数の異なった条件名を使用することができます。
NOTIFY はシグナルの単純な形式、または、同一の PostgreSQL データベースにアクセスするプロセスの集合に対するプロセス間通信機構を提供します。 通知者からリスナ(複数可)に追加的な(単なる条件名を越えた)データを渡すためのデータベース内のテーブルを使用することで、より高レベルの機構を構築することができます。
NOTIFY を特定のテーブルへの変更の発生を知らせるために使用する場合に有用なプログラム開発テクニックは、 NOTIFY をテーブル更新時に発行されるルール内におくことです。 この方法では通知はテーブルが変更された時に自動的に行なわれますので、アプリケーションプログラマが通知の実行を忘れるといった事故を防ぐことができます。
NOTIFY と SQL トランザクションの間にはいくつかの重要な相互作用があります。 まず、NOTIFYがトランザクション内部で実行された場合、通知イベントはトランザクションがコミットされるまで、そして、コミットされない限り配送されません。 トランザクションがアボートしたならば、NOTIFY を含む、トランザクション内で行なわれた全てのコマンドが何の影響も及ぼさないようにするという点から、このことは適切といえます。 しかし、もしユーザが、通知イベントが即座に配送されることを期待していたとすると、このことは不安になることがあります。 次に、監視中のセッションがトランザクション処理中に通知信号を受け取った場合、通知イベントはそのトランザクションが(コミットされるかアボートされるかのどちらかによって)完了するまで、接続しているクライアントに配送されません。 この理由は繰り返しになりますが、通知がトランザクション内に配送され、その後にトランザクションがアボートしたとすると、その通知も何とか取り消したくなりますが、しかし、サーバは一旦クライアントに送信した通知を"取り戻す"ことができないということです。 ですから、通知イベントはトランザクションとトランザクションの合間にのみ配送されます。 この結果、実時間レベルでの信号処理のために NOTIFY を使用するアプリケーションではそのトランザクション処理を短くしておかなければなりません。
NOTIFYは、次の重要な点においてUnixのシグナルと似た動作を行います。 同一の条件名が短期間に連続して複数回発せられた場合、複数のNOTIFYの実行に対して、受信者は1つの通知イベントのみしか受け取らない場合があります。 ですので、通知を受信した回数に依存することはよくない考え方となります。 それよりも、何かに注意をしなければならないアプリケーションを起動させる場合にNOTIFYを使用してください。 そして、何が起こったのかを追跡したり、何回起こったのかを数えたりする場合には、(シーケンスなどの)データベースオブジェクトを使ってください。
NOTIFY を送るクライアントが、その同じ通知名を自分自身が監視していることは良くあることです。 この場合、他のすべての監視を行なっているセッションと全く同様に通知イベントが戻ってきます。 アプリケーションのロジックに依存しますが、これは無駄な作業を行なう結果になることがあります。 例えば、そのセッションが書き出したばかりのデータベースに対する更新を調べるためにテーブルの再読み込みを行うことです。 (通知イベントメッセージ内にある)通知したセッションのサーバプロセスのPIDと(libpqで得られる)自身のセッションのPID が同じかどうかに注意することで、こういった余計な作業を回避できます。 もし同じであれば、その通知イベントは自分自身から跳ね返ってきたものであり、無視することができます。(前の段落で説明したことと反しますが、これは安全なテクニックです。 PostgreSQL は他のセッションからの通知と自身からの通知を別々に保持しておきますので、自分自身の通知を無視したとしても外部からの通知をとり逃すことは起こり得ません。)