automatically
cleaned up by the server at the end of the session.
</para>
<para>
There are two ways to acquire an advisory lock in
<productname>PostgreSQL</productname>: at session level or at
transaction level.
Once acquired at session level, an advisory lock is held until
explicitly released or the session ends. Unlike standard lock requests,
session-level advisory lock requests do not honor transaction semantics:
a lock acquired during a transaction that is later rolled back will still
be held following the rollback, and likewise an unlock is effective even
if the calling transaction fails later. A lock can be acquired multiple
times by its owning process; for each completed lock request there must
be a corresponding unlock request before the lock is actually released.
Transaction-level lock requests, on the other hand, behave more like
regular lock requests: they are automatically released at the end of the
transaction, and there is no explicit unlock operation. This behavior
is often more convenient than the session-level behavior for short-term
usage of an advisory lock.
Session-level and transaction-level lock requests for the same advisory
lock identifier will block each other in the expected way.
If a session already holds a given advisory lock, additional requests by
it will always succeed, even if other sessions are awaiting the lock; this
statement is true regardless of whether the existing lock hold and new
request are at session level or transaction level.
</para>
<para>
Like all locks in
<productname>PostgreSQL</productname>, a complete list of advisory locks
currently held by any session can be found in the <link
linkend="view-pg-locks"><structname>pg_locks</structname></link> system
view.
</para>
<para>
Both advisory locks and regular locks are stored in a shared memory
pool whose size is defined by the configuration variables
<xref linkend="guc-max-locks-per-transaction"/> and
<xref linkend="guc-max-connections"/>.
Care must be taken not to exhaust this
memory or the server will be unable to grant any locks at all.
This imposes an upper limit on the number of advisory locks
grantable by the server, typically in the tens to hundreds of thousands
depending on how the server is configured.
</para>
<para>
In certain cases using advisory locking methods, especially in queries
involving explicit ordering and <literal>LIMIT</literal> clauses, care must be
taken to control the locks acquired because of the order in which SQL
expressions are evaluated. For example:
<screen>
SELECT pg_advisory_lock(id) FROM foo WHERE id = 12345; -- ok
SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- danger!
SELECT pg_advisory_lock(q.id) FROM
(
SELECT id FROM foo WHERE id > 12345 LIMIT 100
) q; -- ok
</screen>
In the above queries, the second form is dangerous because the
<literal>LIMIT</literal> is not guaranteed to be applied before the locking
function is executed. This might cause some locks to be acquired
that the application was not expecting, and hence would fail to release
(until it ends the session).
From the point of view of the application, such locks
would be dangling, although still viewable in
<structname>pg_locks</structname>.
</para>
<para>
The functions provided to manipulate advisory locks are described in
<xref linkend="functions-advisory-locks"/>.
</para>
</sect2>
</sect1>
<sect1 id="applevel-consistency">
<title>Data Consistency Checks at the Application Level</title>
<para>
It is very difficult to enforce business rules regarding data integrity
using Read Committed transactions because the view of the data is
shifting with each statement, and even a single statement