diff --git a/src/gausskernel/storage/access/heap/heapam_visibility.cpp b/src/gausskernel/storage/access/heap/heapam_visibility.cpp index 869e260adad35384b960da227e1ad30d5331d8ea..27bf4103c93324a25d35988d9bdc3b05788540c8 100644 --- a/src/gausskernel/storage/access/heap/heapam_visibility.cpp +++ b/src/gausskernel/storage/access/heap/heapam_visibility.cpp @@ -1945,10 +1945,12 @@ void HeapTupleCheckVisible(Snapshot snapshot, HeapTuple tuple, Buffer buffer) return; LockBuffer(buffer, BUFFER_LOCK_SHARE); if (!HeapTupleSatisfiesVisibility(tuple, snapshot, buffer)) { - LockBuffer(buffer, BUFFER_LOCK_UNLOCK); - ereport(ERROR, - (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), + TransactionId tupleXmin = HeapTupleHeaderGetXmin(BufferGetPage(buffer), tuple->t_data); + if (!TransactionIdIsCurrentTransactionId(tupleXmin)) { + LockBuffer(buffer, BUFFER_LOCK_UNLOCK); + ereport(ERROR, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), errmsg("could not serialize access due to concurrent update"))); + } } LockBuffer(buffer, BUFFER_LOCK_UNLOCK); } diff --git a/src/gausskernel/storage/access/ustore/knl_uvisibility.cpp b/src/gausskernel/storage/access/ustore/knl_uvisibility.cpp index c5cf97b146ad4e22d61ed113f62a9b3dbcf45b39..48beaf0e120423c81d094c805e4ccdcf4969275b 100644 --- a/src/gausskernel/storage/access/ustore/knl_uvisibility.cpp +++ b/src/gausskernel/storage/access/ustore/knl_uvisibility.cpp @@ -172,7 +172,7 @@ static TransactionId UHeapTupleGetModifiedXid(UHeapTuple tup) * Notes: Assumes uheap tuple is valid, and buffer at least share locked. * */ -bool UHeapTupleSatisfiesVisibility(UHeapTuple uhtup, Snapshot snapshot, Buffer buffer) +bool UHeapTupleSatisfiesVisibility(UHeapTuple uhtup, Snapshot snapshot, Buffer buffer, TransactionId *tdXmin) { Assert(uhtup != NULL); if (snapshot->satisfies == SNAPSHOT_DIRTY) { @@ -349,6 +349,9 @@ bool UHeapTupleSatisfiesVisibility(UHeapTuple uhtup, Snapshot snapshot, Buffer b } uheapselect = UHeapCheckCID(op, tdinfo.cid, snapshot->curcid); } + if (tdXmin != NULL) { + *tdXmin = tdinfo.xid; + } if (uheapselect == UVERSION_OLDER || uheapselect == UVERSION_NONE) { return false; } @@ -2390,10 +2393,13 @@ void UHeapTupleCheckVisible(Snapshot snapshot, UHeapTuple tuple, Buffer buffer) if (!IsolationUsesXactSnapshot()) return; LockBuffer(buffer, BUFFER_LOCK_SHARE); - if (!UHeapTupleSatisfiesVisibility(tuple, snapshot, buffer)) { - LockBuffer(buffer, BUFFER_LOCK_UNLOCK); - ereport(ERROR, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), - errmsg("could not serialize access due to concurrent update"))); + TransactionId tdXmin = InvalidTransactionId; + if (!UHeapTupleSatisfiesVisibility(tuple, snapshot, buffer, &tdXmin)) { + if (!TransactionIdIsCurrentTransactionId(tdXmin)) { + LockBuffer(buffer, BUFFER_LOCK_UNLOCK); + ereport(ERROR, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), + errmsg("could not serialize access due to concurrent update"))); + } } LockBuffer(buffer, BUFFER_LOCK_UNLOCK); } diff --git a/src/include/access/ustore/knl_uvisibility.h b/src/include/access/ustore/knl_uvisibility.h index 3aff810eae58cb29e8b5d0e28ae96a324046d59d..34d52c63c576b0d857cc4363f457c44d7e4a2e50 100644 --- a/src/include/access/ustore/knl_uvisibility.h +++ b/src/include/access/ustore/knl_uvisibility.h @@ -52,7 +52,8 @@ bool UHeapTupleFetch(Relation rel, Buffer buffer, OffsetNumber offnum, Snapshot ItemPointer newCtid, bool keepTup, UHeapTupleTransInfo *savedUinfo = NULL, bool *gotTdInfo = NULL, const UHeapTuple *saved_tuple = NULL, int16 lastVar = -1, bool *boolArr = NULL, bool *has_cur_xact_write = NULL); -bool UHeapTupleSatisfiesVisibility(UHeapTuple uhtup, Snapshot snapshot, Buffer buffer); +bool UHeapTupleSatisfiesVisibility(UHeapTuple uhtup, Snapshot snapshot, Buffer buffer, + TransactionId *tdXmin = NULL); extern TransactionId UDiskTupleGetModifiedXid(UHeapDiskTuple diskTup, Page page); TM_Result UHeapTupleSatisfiesUpdate(Relation rel, Snapshot snapshot, ItemPointer tid, UHeapTuple utuple,