Home Explore Blog CI



postgresql

22th chunk of `doc/src/sgml/mvcc.sgml`
3b41bdc368f2de4db44b99c0772d3e96a23fb28cdabb936e0000000100000fa9
 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 &gt; 12345 LIMIT 100; -- danger!
SELECT pg_advisory_lock(q.id) FROM
(
  SELECT id FROM foo WHERE id &gt; 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

Title: Advisory Locks in PostgreSQL
Summary
This section explains the mechanics of advisory locks in PostgreSQL, including how they can be acquired at the session or transaction level, their behavior, and how they can be used to implement custom locking strategies. It also discusses the limitations of advisory locks, such as the risk of exhausting the shared memory pool, and provides examples of how to use them safely, including considerations for queries with explicit ordering and LIMIT clauses.