mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-15 08:20:16 +08:00
LISTEN/NOTIFY doc improvements.
This commit is contained in:
parent
30debec6e5
commit
55a5639e93
@ -10,20 +10,20 @@ LISTEN
|
||||
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
|
||||
@ -33,11 +33,11 @@ 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>
|
||||
|
||||
@ -62,63 +62,95 @@ Outputs
|
||||
<VARIABLELIST>
|
||||
<VARLISTENTRY>
|
||||
<TERM>
|
||||
LISTEN
|
||||
<returnvalue>LISTEN</returnvalue>
|
||||
</TERM>
|
||||
<LISTITEM>
|
||||
<PARA>
|
||||
Message returned upon successful completion of registration.
|
||||
|
||||
</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>
|
||||
</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>
|
||||
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.
|
||||
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>
|
||||
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>
|
||||
|
||||
@ -128,6 +160,7 @@ Usage
|
||||
</TITLE>
|
||||
<PARA>
|
||||
<ProgramListing>
|
||||
-- Configure and execute a listen/notify sequence from psql
|
||||
postgres=> listen virtual;
|
||||
LISTEN
|
||||
postgres=> notify virtual;
|
||||
|
@ -10,22 +10,22 @@ NOTIFY
|
||||
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
|
||||
@ -35,11 +35,11 @@ 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>
|
||||
|
||||
@ -47,7 +47,7 @@ Table or arbitrary relation class used for notification.
|
||||
|
||||
<REFSECT2 ID="R2-SQL-NOTIFY-2">
|
||||
<REFSECT2INFO>
|
||||
<DATE>1998-09-24</DATE>
|
||||
<DATE>1998-10-07</DATE>
|
||||
</REFSECT2INFO>
|
||||
<TITLE>
|
||||
Outputs
|
||||
@ -69,66 +69,141 @@ NOTIFY
|
||||
</TERM>
|
||||
<LISTITEM>
|
||||
<PARA>
|
||||
Notification message from backend.
|
||||
|
||||
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>
|
||||
</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>
|
||||
|
||||
@ -137,19 +212,13 @@ Notes
|
||||
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>
|
||||
|
Loading…
Reference in New Issue
Block a user