Skip to content

[DIV-03] Transactions default to pessimistic mode #439

Description

@s2x

Risk for enterprise users: Medium
Labels: semantic-divergence, area/txnkv, documentation
Reference implementations: client-go txnkv/transaction/txn.go:381 (SetPessimistic, optimistic is the default), client-rust src/transaction/client.rs:174 (begin_optimistic) and :200 (begin_pessimistic)

What differs

TxnKvClient::begin() defaults pessimistic to true: $pessimistic = (bool) ($options['pessimistic'] ?? true); (src/Client/TxnKv/TxnKvClient.php:69).

client-go's KVTxn is optimistic unless SetPessimistic(true) is called (txnkv/transaction/txn.go:381), and the TiKV documentation states plainly that optimistic is the default transaction mode. client-rust makes the choice explicit and unmissable with two separate constructors, begin_optimistic and begin_pessimistic (src/transaction/client.rs:174, :200).

Why it matters

A porter writing $client->begin() in place of Go's store.Begin() will assume they are getting an optimistic transaction, as every other TiKV client and the TiKV documentation lead them to expect. Instead they get pessimistic mode with a different performance profile — an extra KvPessimisticLock round trip per region and a 30-second lock TTL instead of 3 seconds (src/Client/TxnKv/TwoPhaseCommitter.php:55-56) — and, because of DIV-01, a mode whose locking guarantees do not match pessimistic semantics anyway. The combination is the worst of both: the cost of pessimistic mode without its safety.

Workaround available today

Always pass ['pessimistic' => false] explicitly when optimistic behaviour is intended, and never rely on the default.

Implementation sketch

Either flip the default to optimistic to match the official clients, or keep the current default and document it prominently. Flipping is a breaking change and belongs in a major version. The clearer option is to follow client-rust and add explicit beginOptimistic() and beginPessimistic() methods, leaving begin() as a deprecated alias so the ambiguity disappears from new code.

Effort estimate

Small — under a day, plus documentation and a CHANGELOG entry.

Acceptance criteria

  • Explicit beginOptimistic() and beginPessimistic() methods exist.
  • The default mode of begin() is documented in the README and the method docblock.
  • If the default changes, it is released in a major version with a CHANGELOG migration note.

Filed from the Feature gaps vs official clients audit (audit-feature-gaps.md), finding DIV-03.
See the consolidated summary for the root-cause grouping this belongs to.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    auditAdded by audit issue importdocumentationImprovements or additions to documentationfeature-gapAdded by audit issue importseverity:mediumAdded by audit issue import

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions