diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/storage/lmgr/predicate.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 401acdb4715..5096ea0c1c1 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -3757,6 +3757,17 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag) LWLockRelease(partitionLock); LWLockRelease(SerializablePredicateLockListLock); LWLockAcquire(partitionLock, LW_SHARED); + + /* + * The list may have been altered by another process + * while we weren't holding the partition lock. Start + * over at the front. + */ + nextpredlock = (PREDICATELOCK *) + SHMQueueNext(&(target->predicateLocks), + &(target->predicateLocks), + offsetof(PREDICATELOCK, targetLink)); + LWLockAcquire(SerializableXactHashLock, LW_SHARED); } } @@ -3770,7 +3781,19 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag) LWLockRelease(SerializableXactHashLock); LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE); - FlagRWConflict(sxact, (SERIALIZABLEXACT *) MySerializableXact); + /* + * Re-check after getting exclusive lock because the other + * transaction may have flagged a conflict. + */ + if (!SxactIsRolledBack(sxact) + && (!SxactIsCommitted(sxact) + || TransactionIdPrecedes(GetTransactionSnapshot()->xmin, + sxact->finishedBefore)) + && !RWConflictExists(sxact, + (SERIALIZABLEXACT *) MySerializableXact)) + { + FlagRWConflict(sxact, (SERIALIZABLEXACT *) MySerializableXact); + } LWLockRelease(SerializableXactHashLock); LWLockAcquire(SerializableXactHashLock, LW_SHARED); |