LISTEN
</REFNAME>
<REFPURPOSE>
-Listen for notification on a relation
+Listen for notification on a notify condition
</REFPURPOSE>
<REFSYNOPSISDIV>
<REFSYNOPSISDIVINFO>
-<DATE>1998-09-24</DATE>
+<DATE>1998-10-07</DATE>
</REFSYNOPSISDIVINFO>
<SYNOPSIS>
-LISTEN <REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE>
+LISTEN <REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE>
</SYNOPSIS>
<REFSECT2 ID="R2-SQL-LISTEN-1">
<REFSECT2INFO>
-<DATE>1998-09-01</DATE>
+<DATE>1998-10-07</DATE>
</REFSECT2INFO>
<TITLE>
Inputs
<VARIABLELIST>
<VARLISTENTRY>
<TERM>
-<REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE>
+<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE>
</TERM>
<LISTITEM>
<PARA>
-Table object used for notification.
+Name of notify condition.
</VARIABLELIST>
<VARIABLELIST>
<VARLISTENTRY>
<TERM>
-LISTEN
+<returnvalue>LISTEN</returnvalue>
</TERM>
<LISTITEM>
<PARA>
Message returned upon successful completion of registration.
-
-</VARIABLELIST>
+</PARA>
+</LISTITEM>
+</VARLISTENTRY>
+<VARLISTENTRY>
+<TERM>
+<returnvalue>NOTICE Async_Listen: We are already listening on notifyname</returnvalue>
+</TERM>
+<LISTITEM>
+<PARA>
+If this backend is already registered for that notify condition.
+</PARA>
+</LISTITEM>
+</VARLISTENTRY>
+</variablelist>
+</LISTITEM>
+</VARLISTENTRY>
</VARIABLELIST>
-
</REFSECT2>
</REFSYNOPSISDIV>
<REFSECT1 ID="R1-SQL-LISTEN-1">
<REFSECT1INFO>
-<DATE>1998-09-24</DATE>
+<DATE>1998-10-07</DATE>
</REFSECT1INFO>
<TITLE>
Description
</TITLE>
<PARA>
-LISTEN is used to register the current backend as a listener on the relation
-<REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE>.
-When the command
-<command>NOTIFY <REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE></command>
-is called either from within a rule or at the query level, the
-frontend applications corresponding to the listening backends
-are notified. When the backend process exits, this registration
-is cleared.
+LISTEN registers the current <productname>Postgres</productname> backend as a
+listener on the notify condition
+<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE>.
+
+<para>
+Whenever the command
+<command>NOTIFY <REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE></command>
+is invoked, either by this backend or another one connected to
+the same database, all the backends currently listening on that notify
+condition are notified, and each will in turn notify its connected
+frontend application. See the discussion of <command>NOTIFY</command>
+for more information.
<para>
-This event notification is performed through the libpq protocol
-and frontend application interface. The application program
-must call the routine
-<function>PQnotifies</function>
-in order to find out the name of the class to which a given
-notification corresponds. If this code is not included in
-the application, the event notification will be queued and
-never be processed.
+A backend can be deregistered for a given notify condition with the
+<command>UNLISTEN</command> command. Also, a backend's listen registrations
+are automatically cleared when the backend process exits.
+
+<para>
+The method a frontend application must use to detect notify events depends on
+which <productname>Postgres</productname> application programming interface it
+uses. With the basic libpq library, the application issues
+<command>LISTEN</command> as an ordinary SQL command, and then must
+periodically call the routine <function>PQnotifies</function> to find out
+whether any notify events have been received. Other interfaces such as
+libpgtcl provide higher-level methods for handling notify events; indeed,
+with libpgtcl the application programmer should not even issue
+<command>LISTEN</command> or <command>UNLISTEN</command> directly. See the
+documentation for the library you are using for more details.
+
+<para>
+The reference page for <command>NOTIFY</command> contains a more extensive
+discussion of the use of <command>LISTEN</command> and
+<command>NOTIFY</command>.
<REFSECT2 ID="R2-SQL-LISTEN-3">
<REFSECT2INFO>
-<DATE>1998-09-24</DATE>
+<DATE>1998-10-07</DATE>
</REFSECT2INFO>
<TITLE>
Notes
</TITLE>
<para>
-Note that <REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE>
-needs not to be a valid class name but can be any string valid
- as a name up to 32 characters long.
+<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE>
+can be any string valid as a name;
+it need not correspond to the name of any actual table. If
+<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE>
+is enclosed in double-quotes, it need not even be a syntactically
+valid name, but can be any string up to 31 characters long.
<para>
-A restriction in some previous releases of
- <productname>Postgres</productname> that a
-<REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE>
-which does not correspond to an actual table must be enclosed in double-quotes
-is no longer present.
+In some previous releases of
+<productname>Postgres</productname>,
+<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE>
+had to be enclosed in double-quotes when it did not correspond to any existing
+table name, even if syntactically valid as a name. That is no longer required.
</REFSECT2>
</TITLE>
<PARA>
<ProgramListing>
+-- Configure and execute a listen/notify sequence from psql
postgres=> listen virtual;
LISTEN
postgres=> notify virtual;
NOTIFY
</REFNAME>
<REFPURPOSE>
-Signals all frontends and backends listening on a class
+Signals all frontends and backends listening on a notify condition
</REFPURPOSE>
<REFSYNOPSISDIV>
<REFSYNOPSISDIVINFO>
-<DATE>1998-09-24</DATE>
+<DATE>1998-10-07</DATE>
</REFSYNOPSISDIVINFO>
<SYNOPSIS>
<REPLACEABLE CLASS="PARAMETER">
</REPLACEABLE>
-NOTIFY <REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE>
+NOTIFY <REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE>
</SYNOPSIS>
<REFSECT2 ID="R2-SQL-NOTIFY-1">
<REFSECT2INFO>
-<DATE>1998-09-24</DATE>
+<DATE>1998-10-07</DATE>
</REFSECT2INFO>
<TITLE>
Inputs
<VARIABLELIST>
<VARLISTENTRY>
<TERM>
-<REPLACEABLE CLASS="PARAMETER">classname</REPLACEABLE>
+<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE>
</TERM>
<LISTITEM>
<PARA>
-Table or arbitrary relation class used for notification.
+Notify condition to be signaled.
</VARIABLELIST>
<REFSECT2 ID="R2-SQL-NOTIFY-2">
<REFSECT2INFO>
-<DATE>1998-09-24</DATE>
+<DATE>1998-10-07</DATE>
</REFSECT2INFO>
<TITLE>
Outputs
</TERM>
<LISTITEM>
<PARA>
-Notification message from backend.
-
-</VARIABLELIST>
+Acknowledgement that notify command has executed.
+</PARA>
+</LISTITEM>
+</VARLISTENTRY>
+<VARLISTENTRY>
+<TERM>
+Notify events
+</TERM>
+<LISTITEM>
+<PARA>
+Events are delivered to listening frontends; whether and how each frontend
+application reacts depends on its programming.
+</PARA>
+</LISTITEM>
+</VARLISTENTRY>
+</variablelist>
+</LISTITEM>
+</VARLISTENTRY>
</VARIABLELIST>
-
</REFSECT2>
</REFSYNOPSISDIV>
<REFSECT1 ID="R1-SQL-NOTIFY-1">
<REFSECT1INFO>
-<DATE>1998-09-24</DATE>
+<DATE>1998-10-07</DATE>
</REFSECT1INFO>
<TITLE>
Description
</TITLE>
<PARA>
- <command>NOTIFY</command> is used to awaken all sessions which have
-previously executed
- <command>LISTEN <replaceable class="parameter">classname</replaceable></command>.
- This can be used either within an instance-level rule
-as part of the action body or from a normal query.
+The <command>NOTIFY</command> command sends a notify event to each
+frontend application that has previously executed
+<command>LISTEN <replaceable class="parameter">notifyname</replaceable></command>
+for the specified notify condition in the current database.
<para>
- When used from within a normal query,
-this can be thought of as interprocess communication (IPC). When
-used from within a rule, this can be thought of as an alert mechanism.
+The information passed to the frontend for a notify event includes the notify
+condition name and the notifying backend process's PID. It is up to the
+database designer to define the condition names that will be used in a given
+database and what each one means.
+
<para>
- Note that the mere fact that a <command>NOTIFY</command> has been
- executed does not imply anything in particular about the state
- of the class (e.g., that it has been updated),
- nor does the notification protocol transmit any useful information
- other than the class name.
-Therefore, all <command>NOTIFY</command> does is indicate that some backend
- wishes its peers to
- examine <replaceable class="parameter">classname</replaceable>
- in some application-specific way.
+Commonly, the notify condition name is the same as the name of some table in
+the database, and the notify event essentially means "I changed this table,
+take a look at it to see what's new". But no such association is enforced by
+the <command>NOTIFY</command> and <command>LISTEN</command> commands. For
+example, a database designer could use several different condition names
+to signal different sorts of changes to a single table.
+
<para>
- In fact, <replaceable class="parameter">classname</replaceable>
- need not be the name of an SQL class at all.
- It is best thought of as a condition name
- that the application programmer selects.
+<command>NOTIFY</command> provides a simple form of signal or
+IPC (interprocess communication) mechanism for a collection of processes
+accessing the same <productname>Postgres</productname> database.
+Higher-level mechanisms can be built by using tables in the database to
+pass additional data (beyond a mere condition name) from notifier to
+listener(s).
+
<para>
- This event notification is performed through the libpq protocol
- and frontend application interface. The application program
- must call the routine <function>PQnotifies</function>
- in order to find out the name of the class to which a given
- notification corresponds.
-If this code is not included in the application,
-the event notification will be
- queued and never be processed.
-
+When <command>NOTIFY</command> is used to signal the occurrence of changes
+to a particular table, a useful programming technique is to put the
+<command>NOTIFY</command> in a rule that is triggered by table updates.
+In this way, notification happens automatically when the table is changed,
+and the application programmer can't accidentally forget to do it.
+
+<para>
+<command>NOTIFY</command> interacts with SQL transactions in some important
+ways. Firstly, if a <command>NOTIFY</command> 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 <command>NOTIFY</command>. 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 delivered only between transactions. The upshot of this
+is that applications using <command>NOTIFY</command> for real-time signaling
+should try to keep their transactions short.
+
+<para>
+<command>NOTIFY</command> behaves rather like Unix signals in one important
+respect: if the same notify name is signaled multiple times in quick
+succession, recipients may get only one notify event for several executions
+of <command>NOTIFY</command>. So it is a bad idea to depend on the number
+of notifies received; instead use <command>NOTIFY</command> to wake up
+applications that need to pay attention to something, and use a database
+object (such as a sequence) to keep track of what happened or how many times
+it happened.
+
+<para>
+It is common for a frontend that sends <command>NOTIFY</command> to be
+listening on the same notify name itself. In that case it will get back a
+notify event, just like all the other listening frontends. Depending on the
+application logic, this could result in useless work --- for example,
+re-reading a database table to find the same updates that that frontend just
+wrote out. In <productname>Postgres</productname> 6.4 and later, it is
+possible to avoid such extra work by noticing whether the notifying backend
+process's PID (supplied in the notify event message) is the same as one's own
+backend's PID (available from libpq). When they are the same, the notify
+event is one's own work bouncing back, and can be ignored. (Despite what was
+said in the preceding paragraph, this is a safe technique.
+<productname>Postgres</productname> keeps self-notifies separate from notifies
+arriving from other backends, so you cannot miss an outside notify by ignoring
+your own notifies.)
+
<REFSECT2 ID="R2-SQL-NOTIFY-3">
<REFSECT2INFO>
-<DATE>1998-09-24</DATE>
+<DATE>1998-10-07</DATE>
</REFSECT2INFO>
<TITLE>
Notes
</TITLE>
-<PARA>
-</PARA>
+<para>
+<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE>
+can be any string valid as a name;
+it need not correspond to the name of any actual table. If
+<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE>
+is enclosed in double-quotes, it need not even be a syntactically
+valid name, but can be any string up to 31 characters long.
+
+<para>
+In some previous releases of
+<productname>Postgres</productname>,
+<REPLACEABLE CLASS="PARAMETER">notifyname</REPLACEABLE>
+had to be enclosed in double-quotes when it did not correspond to any existing
+table name, even if syntactically valid as a name. That is no longer required.
+
+<para>
+In <productname>Postgres</productname> releases prior to 6.4, the backend
+PID delivered in a notify message is always the PID of the frontend's own
+backend. So it is not possible to distinguish one's own notifies from other
+clients' notifies in those earlier releases.
</REFSECT2>
Usage
</TITLE>
<PARA>
-</PARA>
<ProgramListing>
--- Configure and execute a listen/notify sequence
--- from psql
-CREATE TABLE t (i int4);
-<computeroutput>
-LISTEN t;
-</computeroutput>
-NOTIFY t;
-<computeroutput>
+-- Configure and execute a listen/notify sequence from psql
+postgres=> listen virtual;
+LISTEN
+postgres=> notify virtual;
NOTIFY
-ASYNC NOTIFY of 't' from backend pid '10949' received
-</computeroutput>
+ASYNC NOTIFY of 'virtual' from backend pid '11239' received
</ProgramListing>
</REFSECT1>