From afe381dddffe25ad63382b7f7d7a2ae816aacbd1 Mon Sep 17 00:00:00 2001 From: Liangliang Gu Date: Wed, 16 Dec 2020 16:09:24 +0800 Subject: [PATCH] txn: fix the resolved txn status cache for pessimistic txn (#1868) --- .../tikv/txn/LockResolverClientV4.java | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/tikv-client/src/main/java/com/pingcap/tikv/txn/LockResolverClientV4.java b/tikv-client/src/main/java/com/pingcap/tikv/txn/LockResolverClientV4.java index 744ad53e59..d55d62471a 100644 --- a/tikv-client/src/main/java/com/pingcap/tikv/txn/LockResolverClientV4.java +++ b/tikv-client/src/main/java/com/pingcap/tikv/txn/LockResolverClientV4.java @@ -230,7 +230,13 @@ private TxnStatus getTxnStatusFromLock(BackOffer bo, Lock lock, long callerStart while (true) { try { return getTxnStatus( - bo, lock.getTxnID(), lock.getPrimary(), callerStartTS, currentTS, rollbackIfNotExist); + bo, + lock.getTxnID(), + lock.getPrimary(), + callerStartTS, + currentTS, + rollbackIfNotExist, + lock); } catch (TxnNotFoundException e) { // If the error is something other than txnNotFoundErr, throw the error (network // unavailable, tikv down, backoff timeout etc) to the caller. @@ -270,7 +276,8 @@ private TxnStatus getTxnStatus( ByteString primary, Long callerStartTS, Long currentTS, - boolean rollbackIfNotExist) { + boolean rollbackIfNotExist, + Lock lock) { TxnStatus status = getResolved(txnID); if (status != null) { return status; @@ -346,9 +353,26 @@ private TxnStatus getTxnStatus( status = new TxnStatus(resp.getLockTtl(), 0L, resp.getAction()); } else { status = new TxnStatus(0L, resp.getCommitVersion(), resp.getAction()); - saveResolved(txnID, status); - } + // If the transaction is still valid with ttl greater than zero, do nothing. + // If its status is certain: + // If transaction is already committed, the result could be cached. + // Otherwise: + // If l.LockType is pessimistic lock type: + // - if its primary lock is pessimistic too, the check txn status result should + // not be cached. + // - if its primary lock is prewrite lock type, the check txn status could be + // cached, todo. + // If l.lockType is prewrite lock type: + // - always cache the check txn status result. + // For prewrite locks, their primary keys should ALWAYS be the correct one and will NOT + // change. + if (status.isCommitted() + || (lock != null + && lock.getLockType() != org.tikv.kvproto.Kvrpcpb.Op.PessimisticLock)) { + saveResolved(txnID, status); + } + } return status; } }