Partially roll back overenthusiastic SSI optimization.

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
This commit is contained in:
Robert Haas 2011-04-08 15:29:02 -04:00
parent 9c38bce29c
commit fbc0d07796
1 changed files with 13 additions and 7 deletions

View 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;