Skip to content

Commit

Permalink
Allow configuring the policy when prewrite encounters lock (#1501)
Browse files Browse the repository at this point in the history
 

Signed-off-by: ekexium <[email protected]>
  • Loading branch information
ekexium authored Jan 2, 2025
1 parent 078462f commit 743aec1
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
4 changes: 3 additions & 1 deletion txnkv/transaction/prewrite.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ func (action actionPrewrite) handleSingleBatch(
zap.Uint64("session", c.sessionID),
zap.Uint64("txnID", c.startTS),
zap.Stringer("lock", lock),
zap.Stringer("policy", c.txn.prewriteEncounterLockPolicy),
)
logged[lock.TxnID] = struct{}{}
}
Expand All @@ -457,7 +458,8 @@ func (action actionPrewrite) handleSingleBatch(
// Pessimistic transactions don't need such an optimization. If this key needs a pessimistic lock,
// TiKV will return a PessimisticLockNotFound error directly if it encounters a different lock. Otherwise,
// TiKV returns lock.TTL = 0, and we still need to resolve the lock.
if lock.TxnID > c.startTS && !c.isPessimistic {
if (lock.TxnID > c.startTS && !c.isPessimistic) ||
c.txn.prewriteEncounterLockPolicy == NoResolvePolicy {
return tikverr.NewErrWriteConflictWithArgs(
c.startTS,
lock.TxnID,
Expand Down
29 changes: 29 additions & 0 deletions txnkv/transaction/txn.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,28 @@ type TxnOptions struct {
PipelinedMemDB bool
}

// PrewriteEncounterLockPolicy specifies the policy when prewrite encounters locks.
type PrewriteEncounterLockPolicy int

const (
// TryResolvePolicy is the default one: try to resolve those locks with smaller startTS.
TryResolvePolicy PrewriteEncounterLockPolicy = iota
// NoResolvePolicy means do not resolve, but return write conflict errors directly.
// This can be used to let the upper layer choose to retry in pessimistic mode.
NoResolvePolicy
)

func (p PrewriteEncounterLockPolicy) String() string {
switch p {
case TryResolvePolicy:
return "TryResolvePolicy"
case NoResolvePolicy:
return "NoResolvePolicy"
default:
return "Unknown"
}
}

// KVTxn contains methods to interact with a TiKV transaction.
type KVTxn struct {
snapshot *txnsnapshot.KVSnapshot
Expand Down Expand Up @@ -172,6 +194,8 @@ type KVTxn struct {

isPipelined bool
pipelinedCancel context.CancelFunc

prewriteEncounterLockPolicy PrewriteEncounterLockPolicy
}

// NewTiKVTxn creates a new KVTxn.
Expand Down Expand Up @@ -472,6 +496,11 @@ func (txn *KVTxn) SetAssertionLevel(assertionLevel kvrpcpb.AssertionLevel) {
txn.assertionLevel = assertionLevel
}

// SetPrewriteEncounterLockPolicy specifies the behavior when prewrite encounters locks.
func (txn *KVTxn) SetPrewriteEncounterLockPolicy(policy PrewriteEncounterLockPolicy) {
txn.prewriteEncounterLockPolicy = policy
}

// IsPessimistic returns true if it is pessimistic.
func (txn *KVTxn) IsPessimistic() bool {
return txn.isPessimistic
Expand Down

0 comments on commit 743aec1

Please sign in to comment.