]> granicus.if.org Git - postgresql/commitdiff
Partially roll back overenthusiastic SSI optimization.
authorRobert Haas <rhaas@postgresql.org>
Fri, 8 Apr 2011 19:29:02 +0000 (15:29 -0400)
committerRobert Haas <rhaas@postgresql.org>
Fri, 8 Apr 2011 19:29:02 +0000 (15:29 -0400)
When a regular lock is held, SSI can use that in lieu of a predicate lock
to detect rw conflicts; but if the regular lock is being taken by a
subtransaction, we can't assume that it'll commit, so releasing the
parent transaction's lock in that case is a no-no.

Kevin Grittner

src/backend/storage/lmgr/predicate.c

index 46b86546ee074cda1b7cde47b2a79009fece1e50..11dede9e70b8805635a98f8def33ffd4caf89177 100644 (file)
@@ -3638,14 +3638,20 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
                if (sxact == MySerializableXact)
                {
                        /*
-                        * If we're getting a write lock on the tuple, we don't need a
-                        * predicate (SIREAD) lock. At this point our transaction already
-                        * has an ExclusiveRowLock on the relation, so we are OK to drop
-                        * the predicate lock on the tuple, if found, without fearing that
-                        * another write against the tuple will occur before the MVCC
-                        * information makes it to the buffer.
+                        * If we're getting a write lock on the tuple and we're not in a
+                        * subtransaction, we don't need a predicate (SIREAD) lock.  We
+                        * can't use this optimization within a subtransaction because
+                        * the subtransaction could be rolled back, and we would be left
+                        * without any lock at the top level.
+                        * 
+                        * At this point our transaction already has an ExclusiveRowLock
+                        * on the relation, so we are OK to drop the predicate lock on
+                        * the tuple, if found, without fearing that another write
+                        * against the tuple will occur before the MVCC information
+                        * makes it to the buffer.
                         */
-                       if (GET_PREDICATELOCKTARGETTAG_OFFSET(*targettag))
+                       if (!IsSubTransaction()
+                               && GET_PREDICATELOCKTARGETTAG_OFFSET(*targettag))
                        {
                                uint32          predlockhashcode;
                                PREDICATELOCKTARGET *rmtarget = NULL;