*** a/src/backend/storage/lmgr/predicate.c --- b/src/backend/storage/lmgr/predicate.c *************** *** 3635,3649 **** CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag) offsetof(PREDICATELOCK, targetLink)); sxact = predlock->tag.myXact; ! 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 (GET_PREDICATELOCKTARGETTAG_OFFSET(*targettag)) { --- 3635,3654 ---- offsetof(PREDICATELOCK, targetLink)); sxact = predlock->tag.myXact; ! if (sxact == MySerializableXact && !IsSubTransaction()) { /* ! * 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)) {