]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Document the recently-understood hazard that a rollback can release row-level
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 1 Dec 2006 20:50:06 +0000 (20:50 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 1 Dec 2006 20:50:06 +0000 (20:50 +0000)
locks that logically should not be released, because when a subtransaction
overwrites XMAX all knowledge of the previous lock state is lost.  It seems
unlikely that we will be able to fix this before 8.3...

doc/src/sgml/ref/select.sgml

index c528010723b8f31c95c2a3e86551b977e2441c7e..172345e412a8caa687649276b0821b7677eff89e 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.80.4.2 2005/04/22 15:53:27 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.80.4.3 2006/12/01 20:50:06 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -818,6 +818,38 @@ FOR UPDATE [ OF <replaceable class="parameter">table_name</replaceable> [, ...]
     rows; for example it can't be used with aggregation.
    </para>
 
+   <para>
+    <literal>FOR UPDATE</literal> may appear before
+    <literal>LIMIT</literal> for compatibility with
+    <productname>PostgreSQL</productname> versions before 7.3.  It
+    effectively executes after <literal>LIMIT</literal>, however, and
+    so that is the recommended place to write it.
+   </para>
+
+  <caution>
+   <para>
+    Avoid locking a row and then modifying it within a later savepoint or
+    <application>PL/pgSQL</application> exception block.  A subsequent
+    rollback would cause the lock to be lost.  For example,
+<programlisting>
+BEGIN;
+SELECT * FROM mytable WHERE key = 1 FOR UPDATE;
+SAVEPOINT s;
+UPDATE mytable SET ... WHERE key = 1;
+ROLLBACK TO s;
+</programlisting>
+    After the <command>ROLLBACK</>, the row is effectively unlocked, rather
+    than returned to its pre-savepoint state of being locked but not modified.
+    This hazard occurs if a row locked in the current transaction is updated
+    or deleted: the former lock state is forgotten.  If the transaction is then
+    rolled back to a state between the original locking command and the
+    subsequent change, the row will appear not to be locked at all.  This is
+    an implementation deficiency which will be addressed in a future release
+    of <productname>PostgreSQL</productname>.
+   </para>
+  </caution>
+
+  <caution>
    <para>
     It is possible for a <command>SELECT</> command using both 
     <literal>LIMIT</literal> and  <literal>FOR UPDATE</literal> 
@@ -827,14 +859,7 @@ FOR UPDATE [ OF <replaceable class="parameter">table_name</replaceable> [, ...]
     Once the <literal>SELECT</> unblocks, the query qualification might not
     be met and the row not be returned by <literal>SELECT</>.
    </para>
-
-   <para>
-    <literal>FOR UPDATE</literal> may appear before
-    <literal>LIMIT</literal> for compatibility with
-    <productname>PostgreSQL</productname> versions before 7.3.  It
-    effectively executes after <literal>LIMIT</literal>, however, and
-    so that is the recommended place to write it.
-   </para>
+  </caution>
   </refsect2>
  </refsect1>