Skip to content

Support fair/aggressive pessimistic locking (WakeUpModeForceLock) to lock-with-conflict instead of surfacing WriteConflict #546

Description

@eduralph

Today (correct, by design)

A pessimistic get_for_update / lock_keys that waits on another transaction's
lock and is then woken by TiKV gets a genuine WriteConflict
(reason: PessimisticRetry) whenever the key was committed by another
transaction at a commit_ts greater than this request's for_update_ts.
client-rust surfaces it as
PessimisticLockError { inner: MultipleKeyErrors([KeyError { .. WriteConflict }]), .. }
with no retry (Transaction::pessimistic_lock in src/transaction/transaction.rs;
new_pessimistic_lock_request in src/transaction/requests.rs always uses the
default WakeUpModeNormal).

This is correct and matches client-go's default LockKeys, which likewise
returns ErrWriteConflict to the caller — so it is not a bug. The caller is
expected to restart at a fresh for_update_ts. (For completeness: the
"transparent retry with a new for_update_ts" often attributed to the Go client
actually lives one layer up in TiDB — pkg/executor/adapter.go: handlePessimisticLockError — not in client-go itself.)

Gap (a missing feature)

client-rust has no equivalent of client-go's opt-in fair / aggressive
locking
: StartAggressiveLocking(), which for a single-key LockKeys sends
WakeUpModeForceLock (tikv/client-go txnkv/transaction/txn.go). In that mode
TiKV acquires the lock despite the conflict and returns the latest value plus
LockedWithConflictTS instead of an error, so the caller can proceed at the
higher timestamp without abandoning the lock attempt.

client-rust already carries the generated proto for this
(PessimisticLockWakeUpMode_WakeUpModeForceLock, and the response
results / locked_with_conflict_ts fields, in src/generated/kvrpcpb.rs) but
never sets wake_up_mode and never reads results.

Proposal

  1. Add opt-in fair/aggressive locking: allow sending WakeUpModeForceLock and
    decode the results / locked_with_conflict_ts fields, so a single-key
    pessimistic lock can lock-with-conflict rather than surface an error.
  2. (Optional) Provide a small retry-on-WriteConflict helper for
    WakeUpModeNormal users, since the equivalent driver logic lives in TiDB and
    is absent from the pure-Rust stack.

This is a feature-parity enhancement; the current default behavior would be
unchanged.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    contributionThis PR is from a community contributor.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions