From e92212330770464415d676bd2a15399a8129e911 Mon Sep 17 00:00:00 2001 From: GreatRiver Date: Thu, 25 Jun 2026 14:20:28 +0800 Subject: [PATCH] fix lockservice orphan remote txn validation --- pkg/lockservice/orphan_txn_test.go | 14 ++++++++++++++ pkg/lockservice/service.go | 8 +++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/pkg/lockservice/orphan_txn_test.go b/pkg/lockservice/orphan_txn_test.go index 4641394c3da9e..2d8f1b3b7d20c 100644 --- a/pkg/lockservice/orphan_txn_test.go +++ b/pkg/lockservice/orphan_txn_test.go @@ -804,6 +804,20 @@ func TestValidTxnWithInvalidRemoteTxn(t *testing.T) { require.False(t, hold.isValidRemoteTxn(pb.WaitTxn{TxnID: []byte{1}, CreatedOn: "s0"})) } +func TestValidTxnWithInactiveRemoteTxnAndNotifyFoundCommitting(t *testing.T) { + hold := newMapBasedTxnHandler( + "s1", + getLogger(""), + newFixedSlicePool(16), + func(sid string) (bool, error) { return false, nil }, + func(ot []pb.OrphanTxn) ([][]byte, error) { return [][]byte{{1}}, nil }, + func(txn pb.WaitTxn) (bool, error) { + return false, nil + }, + ).(*mapBasedTxnHolder) + require.True(t, hold.isValidRemoteTxn(pb.WaitTxn{TxnID: []byte{1}, CreatedOn: "s0"})) +} + func TestValidTxnWithInvalidRemoteTxnAndNotifyOK(t *testing.T) { hold := newMapBasedTxnHandler( "s1", diff --git a/pkg/lockservice/service.go b/pkg/lockservice/service.go index 4f78b720e0db0..e6fc1c2eab971 100644 --- a/pkg/lockservice/service.go +++ b/pkg/lockservice/service.go @@ -1001,7 +1001,13 @@ func (h *mapBasedTxnHolder) isValidRemoteTxn(txn pb.WaitTxn) bool { valid, err := h.validTxn(txn) if err == nil { - return valid + if valid { + return true + } + // A remote CN active-txn miss does not prove the txn is safe to unlock. + // The commit response may be lost after TN has already committed it, so + // require the allocator to confirm the txn cannot still be committing. + return !h.canUnlockRemoteTxn(txn) } logValidTxnFailed(h.logger, txn, err) if isRetryError(err) {