mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Add documentation for new in-core advisory lock functions. Merlin Moncure
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
				
			|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.338 2006/09/16 00:30:13 momjian Exp $ -->
 | 
					<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.339 2006/09/20 23:43:21 tgl Exp $ -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 <chapter id="functions">
 | 
					 <chapter id="functions">
 | 
				
			||||||
  <title>Functions and Operators</title>
 | 
					  <title>Functions and Operators</title>
 | 
				
			||||||
@@ -10577,15 +10577,205 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
 | 
				
			|||||||
   </indexterm>
 | 
					   </indexterm>
 | 
				
			||||||
   <para>
 | 
					   <para>
 | 
				
			||||||
    <function>pg_stat_file</> returns a record containing the file
 | 
					    <function>pg_stat_file</> returns a record containing the file
 | 
				
			||||||
    size, last accessed time stamp, last modified time stamp, 
 | 
					    size, last accessed time stamp, last modified time stamp,
 | 
				
			||||||
    last file status change time stamp (Unix platforms only), 
 | 
					    last file status change time stamp (Unix platforms only),
 | 
				
			||||||
    file creation timestamp (Windows only), and a <type>boolean</type> indicating 
 | 
					    file creation timestamp (Windows only), and a <type>boolean</type>
 | 
				
			||||||
    if it is a directory.  Typical usages include:
 | 
					    indicating if it is a directory.  Typical usages include:
 | 
				
			||||||
<programlisting>
 | 
					<programlisting>
 | 
				
			||||||
SELECT * FROM pg_stat_file('filename');
 | 
					SELECT * FROM pg_stat_file('filename');
 | 
				
			||||||
SELECT (pg_stat_file('filename')).modification;
 | 
					SELECT (pg_stat_file('filename')).modification;
 | 
				
			||||||
</programlisting>
 | 
					</programlisting>
 | 
				
			||||||
   </para>
 | 
					   </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   <para>
 | 
				
			||||||
 | 
					    The functions shown in <xref linkend="functions-advisory-locks"> manage
 | 
				
			||||||
 | 
					    advisory locks.  For details about proper usage of these functions, see
 | 
				
			||||||
 | 
					    <xref linkend="advisory-locks">.
 | 
				
			||||||
 | 
					   </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   <table id="functions-advisory-locks">
 | 
				
			||||||
 | 
					    <title>Advisory Lock Functions</title>
 | 
				
			||||||
 | 
					    <tgroup cols="3">
 | 
				
			||||||
 | 
					     <thead>
 | 
				
			||||||
 | 
					      <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
 | 
				
			||||||
 | 
					      </row>
 | 
				
			||||||
 | 
					     </thead>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     <tbody>
 | 
				
			||||||
 | 
					      <row>
 | 
				
			||||||
 | 
					       <entry>
 | 
				
			||||||
 | 
					        <literal><function>pg_advisory_lock</function>(<parameter>key</> <type>bigint</>)</literal>
 | 
				
			||||||
 | 
					       </entry>
 | 
				
			||||||
 | 
					       <entry><type>void</type></entry>
 | 
				
			||||||
 | 
					       <entry>Obtain exclusive advisory lock</entry>
 | 
				
			||||||
 | 
					      </row>
 | 
				
			||||||
 | 
					      <row>
 | 
				
			||||||
 | 
					       <entry>
 | 
				
			||||||
 | 
					        <literal><function>pg_advisory_lock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
 | 
				
			||||||
 | 
					       </entry>
 | 
				
			||||||
 | 
					       <entry><type>void</type></entry>
 | 
				
			||||||
 | 
					       <entry>Obtain exclusive advisory lock</entry>
 | 
				
			||||||
 | 
					      </row>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <row>
 | 
				
			||||||
 | 
					       <entry>
 | 
				
			||||||
 | 
					        <literal><function>pg_advisory_lock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
 | 
				
			||||||
 | 
					       </entry>
 | 
				
			||||||
 | 
					       <entry><type>void</type></entry>
 | 
				
			||||||
 | 
					       <entry>Obtain shared advisory lock</entry>
 | 
				
			||||||
 | 
					      </row>
 | 
				
			||||||
 | 
					      <row>
 | 
				
			||||||
 | 
					       <entry>
 | 
				
			||||||
 | 
					        <literal><function>pg_advisory_lock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
 | 
				
			||||||
 | 
					       </entry>
 | 
				
			||||||
 | 
					       <entry><type>void</type></entry>
 | 
				
			||||||
 | 
					       <entry>Obtain shared advisory lock</entry>
 | 
				
			||||||
 | 
					      </row>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <row>
 | 
				
			||||||
 | 
					       <entry>
 | 
				
			||||||
 | 
					        <literal><function>pg_try_advisory_lock</function>(<parameter>key</> <type>bigint</>)</literal>
 | 
				
			||||||
 | 
					       </entry>
 | 
				
			||||||
 | 
					       <entry><type>boolean</type></entry>
 | 
				
			||||||
 | 
					       <entry>Obtain exclusive advisory lock if available</entry>
 | 
				
			||||||
 | 
					      </row>
 | 
				
			||||||
 | 
					      <row>
 | 
				
			||||||
 | 
					       <entry>
 | 
				
			||||||
 | 
					        <literal><function>pg_try_advisory_lock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
 | 
				
			||||||
 | 
					       </entry>
 | 
				
			||||||
 | 
					       <entry><type>boolean</type></entry>
 | 
				
			||||||
 | 
					       <entry>Obtain exclusive advisory lock if available</entry>
 | 
				
			||||||
 | 
					      </row>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <row>
 | 
				
			||||||
 | 
					       <entry>
 | 
				
			||||||
 | 
					        <literal><function>pg_try_advisory_lock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
 | 
				
			||||||
 | 
					       </entry>
 | 
				
			||||||
 | 
					       <entry><type>boolean</type></entry>
 | 
				
			||||||
 | 
					       <entry>Obtain shared advisory lock if available</entry>
 | 
				
			||||||
 | 
					      </row>
 | 
				
			||||||
 | 
					      <row>
 | 
				
			||||||
 | 
					       <entry>
 | 
				
			||||||
 | 
					        <literal><function>pg_try_advisory_lock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
 | 
				
			||||||
 | 
					       </entry>
 | 
				
			||||||
 | 
					       <entry><type>boolean</type></entry>
 | 
				
			||||||
 | 
					       <entry>Obtain shared advisory lock if available</entry>
 | 
				
			||||||
 | 
					      </row>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <row>
 | 
				
			||||||
 | 
					       <entry>
 | 
				
			||||||
 | 
					        <literal><function>pg_advisory_unlock</function>(<parameter>key</> <type>bigint</>)</literal>
 | 
				
			||||||
 | 
					       </entry>
 | 
				
			||||||
 | 
					       <entry><type>boolean</type></entry>
 | 
				
			||||||
 | 
					       <entry>Release an exclusive advisory lock</entry>
 | 
				
			||||||
 | 
					      </row>
 | 
				
			||||||
 | 
					      <row>
 | 
				
			||||||
 | 
					       <entry>
 | 
				
			||||||
 | 
					        <literal><function>pg_advisory_unlock</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
 | 
				
			||||||
 | 
					       </entry>
 | 
				
			||||||
 | 
					       <entry><type>boolean</type></entry>
 | 
				
			||||||
 | 
					       <entry>Release an exclusive advisory lock</entry>
 | 
				
			||||||
 | 
					      </row>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <row>
 | 
				
			||||||
 | 
					       <entry>
 | 
				
			||||||
 | 
					        <literal><function>pg_advisory_unlock_shared</function>(<parameter>key</> <type>bigint</>)</literal>
 | 
				
			||||||
 | 
					       </entry>
 | 
				
			||||||
 | 
					       <entry><type>boolean</type></entry>
 | 
				
			||||||
 | 
					       <entry>Release a shared advisory lock</entry>
 | 
				
			||||||
 | 
					      </row>
 | 
				
			||||||
 | 
					      <row>
 | 
				
			||||||
 | 
					       <entry>
 | 
				
			||||||
 | 
					        <literal><function>pg_advisory_unlock_shared</function>(<parameter>key1</> <type>int</>, <parameter>key2</> <type>int</>)</literal>
 | 
				
			||||||
 | 
					       </entry>
 | 
				
			||||||
 | 
					       <entry><type>boolean</type></entry>
 | 
				
			||||||
 | 
					       <entry>Release a shared advisory lock</entry>
 | 
				
			||||||
 | 
					      </row>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <row>
 | 
				
			||||||
 | 
					       <entry>
 | 
				
			||||||
 | 
					        <literal><function>pg_advisory_unlock_all</function>()</literal>
 | 
				
			||||||
 | 
					       </entry>
 | 
				
			||||||
 | 
					       <entry><type>void</type></entry>
 | 
				
			||||||
 | 
					       <entry>Release all advisory locks held by the current session</entry>
 | 
				
			||||||
 | 
					      </row>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     </tbody>
 | 
				
			||||||
 | 
					    </tgroup>
 | 
				
			||||||
 | 
					   </table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   <indexterm zone="functions-admin">
 | 
				
			||||||
 | 
					    <primary>pg_advisory_lock</primary>
 | 
				
			||||||
 | 
					   </indexterm>
 | 
				
			||||||
 | 
					   <para>
 | 
				
			||||||
 | 
					    <function>pg_advisory_lock</> locks an application-defined resource,
 | 
				
			||||||
 | 
					    which may be identified either by a single 64-bit key value or two
 | 
				
			||||||
 | 
					    32-bit key values (note that these two key spaces do not overlap).  If
 | 
				
			||||||
 | 
					    another session already holds a lock on the same resource, the
 | 
				
			||||||
 | 
					    function will wait until the resource becomes available.  The lock
 | 
				
			||||||
 | 
					    is exclusive.  Multiple lock requests stack, so that if the same resource
 | 
				
			||||||
 | 
					    is locked three times it must be also unlocked three times to be
 | 
				
			||||||
 | 
					    released for other sessions' use.
 | 
				
			||||||
 | 
					   </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   <indexterm zone="functions-admin">
 | 
				
			||||||
 | 
					    <primary>pg_advisory_lock_shared</primary>
 | 
				
			||||||
 | 
					   </indexterm>
 | 
				
			||||||
 | 
					   <para>
 | 
				
			||||||
 | 
					    <function>pg_advisory_lock_shared</> works the same as
 | 
				
			||||||
 | 
					    <function>pg_advisory_lock</>,
 | 
				
			||||||
 | 
					    except the lock can be shared with other sessions requesting shared locks.
 | 
				
			||||||
 | 
					    Only would-be exclusive lockers are locked out.
 | 
				
			||||||
 | 
					   </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   <indexterm zone="functions-admin">
 | 
				
			||||||
 | 
					    <primary>pg_try_advisory_lock</primary>
 | 
				
			||||||
 | 
					   </indexterm>
 | 
				
			||||||
 | 
					   <para>
 | 
				
			||||||
 | 
					    <function>pg_try_advisory_lock</> is similar to
 | 
				
			||||||
 | 
					    <function>pg_advisory_lock</>, except the function will not wait for the
 | 
				
			||||||
 | 
					    lock to become available.  It will either obtain the lock immediately and
 | 
				
			||||||
 | 
					    return <literal>true</>, or return <literal>false</> if the lock cannot be
 | 
				
			||||||
 | 
					    acquired now.
 | 
				
			||||||
 | 
					   </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   <indexterm zone="functions-admin">
 | 
				
			||||||
 | 
					    <primary>pg_try_advisory_lock_shared</primary>
 | 
				
			||||||
 | 
					   </indexterm>
 | 
				
			||||||
 | 
					   <para>
 | 
				
			||||||
 | 
					    <function>pg_try_advisory_lock_shared</> works the same as
 | 
				
			||||||
 | 
					    <function>pg_try_advisory_lock</>, except it attempts to acquire
 | 
				
			||||||
 | 
					    shared rather than exclusive lock.
 | 
				
			||||||
 | 
					   </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   <indexterm zone="functions-admin">
 | 
				
			||||||
 | 
					    <primary>pg_advisory_unlock</primary>
 | 
				
			||||||
 | 
					   </indexterm>
 | 
				
			||||||
 | 
					   <para>
 | 
				
			||||||
 | 
					    <function>pg_advisory_unlock</> will release a previously-acquired
 | 
				
			||||||
 | 
					    exclusive advisory lock.  It
 | 
				
			||||||
 | 
					    will return <literal>true</> if the lock is successfully released.
 | 
				
			||||||
 | 
					    If the lock was in fact not held, it will return <literal>false</>,
 | 
				
			||||||
 | 
					    and in addition, an SQL warning will be raised by the server.
 | 
				
			||||||
 | 
					   </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   <indexterm zone="functions-admin">
 | 
				
			||||||
 | 
					    <primary>pg_advisory_unlock_shared</primary>
 | 
				
			||||||
 | 
					   </indexterm>
 | 
				
			||||||
 | 
					   <para>
 | 
				
			||||||
 | 
					    <function>pg_advisory_unlock_shared</> works the same as
 | 
				
			||||||
 | 
					    <function>pg_advisory_unlock</>, 
 | 
				
			||||||
 | 
					    except to release a shared advisory lock.
 | 
				
			||||||
 | 
					   </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   <indexterm zone="functions-admin">
 | 
				
			||||||
 | 
					    <primary>pg_advisory_unlock_all</primary>
 | 
				
			||||||
 | 
					   </indexterm>
 | 
				
			||||||
 | 
					   <para>
 | 
				
			||||||
 | 
					    <function>pg_advisory_unlock_all</> will release all advisory locks
 | 
				
			||||||
 | 
					    held by the current session.  (This function is implicitly invoked
 | 
				
			||||||
 | 
					    at session end, even if the client disconnects ungracefully.)
 | 
				
			||||||
 | 
					   </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  </sect1>
 | 
					  </sect1>
 | 
				
			||||||
</chapter>
 | 
					</chapter>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/mvcc.sgml,v 2.62 2006/09/18 12:11:36 teodor Exp $ -->
 | 
					<!-- $PostgreSQL: pgsql/doc/src/sgml/mvcc.sgml,v 2.63 2006/09/20 23:43:22 tgl Exp $ -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 <chapter id="mvcc">
 | 
					 <chapter id="mvcc">
 | 
				
			||||||
  <title>Concurrency Control</title>
 | 
					  <title>Concurrency Control</title>
 | 
				
			||||||
@@ -25,10 +25,10 @@
 | 
				
			|||||||
   </indexterm>
 | 
					   </indexterm>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   <para>
 | 
					   <para>
 | 
				
			||||||
    Unlike traditional database systems which use locks for concurrency control,
 | 
					    <productname>PostgreSQL</productname> provides a rich set of tools 
 | 
				
			||||||
    <productname>PostgreSQL</productname>
 | 
					    for developers to manage concurrent access to data.  Internally,
 | 
				
			||||||
    maintains data consistency by using a multiversion model
 | 
					    data consistency is maintained by using a multiversion 
 | 
				
			||||||
    (Multiversion Concurrency Control, <acronym>MVCC</acronym>). 
 | 
					    model (Multiversion Concurrency Control, <acronym>MVCC</acronym>). 
 | 
				
			||||||
    This means that while querying a database each transaction sees
 | 
					    This means that while querying a database each transaction sees
 | 
				
			||||||
    a snapshot of data (a <firstterm>database version</firstterm>)
 | 
					    a snapshot of data (a <firstterm>database version</firstterm>)
 | 
				
			||||||
    as it was some
 | 
					    as it was some
 | 
				
			||||||
@@ -36,7 +36,10 @@
 | 
				
			|||||||
    This protects the transaction from viewing inconsistent data that
 | 
					    This protects the transaction from viewing inconsistent data that
 | 
				
			||||||
    could be caused by (other) concurrent transaction updates on the same
 | 
					    could be caused by (other) concurrent transaction updates on the same
 | 
				
			||||||
    data rows, providing <firstterm>transaction isolation</firstterm>
 | 
					    data rows, providing <firstterm>transaction isolation</firstterm>
 | 
				
			||||||
    for each database session.
 | 
					    for each database session.  <acronym>MVCC</acronym>, by eschewing
 | 
				
			||||||
 | 
					    explicit locking methodologies of traditional database systems,
 | 
				
			||||||
 | 
					    minimizes lock contention in order to allow for reasonable 
 | 
				
			||||||
 | 
					    performance in multiuser environments.
 | 
				
			||||||
   </para>
 | 
					   </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   <para>
 | 
					   <para>
 | 
				
			||||||
@@ -52,7 +55,9 @@
 | 
				
			|||||||
    <productname>PostgreSQL</productname> for applications that cannot
 | 
					    <productname>PostgreSQL</productname> for applications that cannot
 | 
				
			||||||
    adapt easily to <acronym>MVCC</acronym> behavior.  However, proper
 | 
					    adapt easily to <acronym>MVCC</acronym> behavior.  However, proper
 | 
				
			||||||
    use of <acronym>MVCC</acronym> will generally provide better
 | 
					    use of <acronym>MVCC</acronym> will generally provide better
 | 
				
			||||||
    performance than locks.
 | 
					    performance than locks.  In addition, application-defined advisory
 | 
				
			||||||
 | 
					    locks provide a mechanism for acquiring locks that are not tied
 | 
				
			||||||
 | 
					    to a single transaction.
 | 
				
			||||||
   </para>
 | 
					   </para>
 | 
				
			||||||
  </sect1>
 | 
					  </sect1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -859,6 +864,83 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
 | 
				
			|||||||
     (e.g., while waiting for user input).
 | 
					     (e.g., while waiting for user input).
 | 
				
			||||||
    </para>
 | 
					    </para>
 | 
				
			||||||
   </sect2>
 | 
					   </sect2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   <sect2 id="advisory-locks">
 | 
				
			||||||
 | 
					    <title>Advisory Locks</title>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <indexterm zone="advisory-locks">
 | 
				
			||||||
 | 
					     <primary>lock</primary>
 | 
				
			||||||
 | 
					     <secondary>advisory</secondary>
 | 
				
			||||||
 | 
					    </indexterm>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <para>
 | 
				
			||||||
 | 
					     <productname>PostgreSQL</productname> provides a means for
 | 
				
			||||||
 | 
					     creating locks that have application-defined meanings.  These are
 | 
				
			||||||
 | 
					     called <firstterm>advisory locks</>, because the system does not
 | 
				
			||||||
 | 
					     enforce their use — it is up to the application to use them
 | 
				
			||||||
 | 
					     correctly.  Advisory locks can be useful for locking strategies
 | 
				
			||||||
 | 
					     that are an awkward fit for the MVCC model.  Once acquired, an
 | 
				
			||||||
 | 
					     advisory lock is held until explicitly released or the session ends.
 | 
				
			||||||
 | 
					     Unlike standard locks, advisory locks do not
 | 
				
			||||||
 | 
					     honor transaction semantics.  For example, a lock acquired during a
 | 
				
			||||||
 | 
					     transaction that is later rolled back will still be held following the
 | 
				
			||||||
 | 
					     rollback.  The same lock can be acquired multiple times by its
 | 
				
			||||||
 | 
					     owning process: for each lock request there must be a corresponding
 | 
				
			||||||
 | 
					     unlock request before the lock is actually released.  (If a session
 | 
				
			||||||
 | 
					     already holds a given lock, additional requests will always succeed, even
 | 
				
			||||||
 | 
					     if other sessions are awaiting the lock.)  Like all locks in
 | 
				
			||||||
 | 
					     <productname>PostgreSQL</productname>, a complete list of advisory
 | 
				
			||||||
 | 
					     locks currently held by any session can be found in the system view
 | 
				
			||||||
 | 
					     <structname>pg_locks</structname>.
 | 
				
			||||||
 | 
					    </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <para>
 | 
				
			||||||
 | 
					     Advisory locks are allocated out of 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 not be able 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>
 | 
				
			||||||
 | 
					     A common use of advisory locks is to emulate pessimistic locking
 | 
				
			||||||
 | 
					     strategies typical of so called <quote>flat file</> data management
 | 
				
			||||||
 | 
					     systems.
 | 
				
			||||||
 | 
					     While a flag stored in a table could be used for the same purpose,
 | 
				
			||||||
 | 
					     advisory locks are faster, avoid MVCC bloat, and are automatically
 | 
				
			||||||
 | 
					     cleaned up by the server at the end of the session.
 | 
				
			||||||
 | 
					     In certain cases using this method, especially in queries
 | 
				
			||||||
 | 
					     involving explicit ordering and <literal>LIMIT</> 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</> 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>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <sect1 id="applevel-consistency">
 | 
					  <sect1 id="applevel-consistency">
 | 
				
			||||||
@@ -993,12 +1075,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
 | 
				
			|||||||
      </term>
 | 
					      </term>
 | 
				
			||||||
      <listitem>
 | 
					      <listitem>
 | 
				
			||||||
       <para>
 | 
					       <para>
 | 
				
			||||||
		Short-term share/exclusive page-level locks are used for 
 | 
					        Short-term share/exclusive page-level locks are used for
 | 
				
			||||||
		read/write access. Locks are released immediately after each
 | 
					        read/write access. Locks are released immediately after each
 | 
				
			||||||
		index row is fetched or inserted. But note that a GIN-indexed
 | 
					        index row is fetched or inserted. But note that a GIN-indexed
 | 
				
			||||||
		value insertion usually produces several index key insertions
 | 
					        value insertion usually produces several index key insertions
 | 
				
			||||||
		per row, so GIN may do substantial work for a single value's
 | 
					        per row, so GIN may do substantial work for a single value's
 | 
				
			||||||
		insertion.
 | 
					        insertion.
 | 
				
			||||||
       </para>
 | 
					       </para>
 | 
				
			||||||
      </listitem>
 | 
					      </listitem>
 | 
				
			||||||
     </varlistentry>
 | 
					     </varlistentry>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user