Open-Source Wikis

/

etcd

/

Features

/

Transactions

etcd-io/etcd

Transactions

A Txn is etcd's atomic compare-and-swap-or-else primitive. It evaluates a set of Compare predicates against the current state and, depending on the result, applies a Then or Else list of operations — all under a single MVCC revision.

Wire-level shape

api/etcdserverpb/rpc.proto defines:

rpc Txn(TxnRequest) returns (TxnResponse) {}

with:

  • Compare[] — predicates over version, create_revision, mod_revision, value, or lease.
  • RequestOp[] success / failure — operations executed when all compares succeed (or any fails). Each RequestOp is itself a Range, Put, DeleteRange, or nested Txn.

Evaluation

Source: server/etcdserver/txn/.

graph TD
    txn[TxnRequest] --> ev[txn.Txn]
    ev --> guard[txn.checkRange + auth]
    guard --> compare[evaluate Compare list]
    compare -->|all true| then[execute Then ops]
    compare -->|any false| els[execute Else ops]
    then --> rev[bump MVCC revision]
    els --> rev
    rev --> resp[TxnResponse]

Key invariants enforced by server/etcdserver/txn/:

  • The same key cannot be modified twice in one txn.
  • Nested Txns share the parent's auth context but get their own permission checks.
  • Range reads inside the txn observe the pre-txn state (snapshot semantics).

Apply path

Like every other write, Txn is proposed via Raft. On the leader the request is forwarded through EtcdServer.Txn (server/etcdserver/v3_server.go); on every member the apply layer evaluates it deterministically (server/etcdserver/apply/uber_applier.goapplierV3backend). Determinism is non-negotiable: every member must arrive at the same success/failure outcome, the same revision bumps, and the same key writes.

Auth in transactions

Permission checks have to consider every operation in the txn — including those that won't run because of the compare result, since revealing whether a key changed is itself information leakage. Recent commits in this area (70a2b4871, 4bc674b79, d97dfbc3b, c5893b5e6) tightened RBAC in nested-txn corner cases involving Put-with-lease and prev_kv. See security/ for the threat model.

Client side

  • client/v3/txn.go builds *pb.TxnRequests. The fluent API: client.Txn(ctx).If(...).Then(...).Else(...).Commit().
  • client/v3/clientv3util/key_compare.go provides the standard KeyExists / KeyMissing shorthand compares.
  • concurrency.STM (client/v3/concurrency/stm.go) layers a software-transactional-memory style API on top of Txn for read-then-conditional-write workflows.

Limits

  • --max-txn-ops (default 128) caps the total operations across success + failure.
  • --max-request-bytes (default ~1.5 MiB) caps the wire-encoded size of a single proposal.
  • Operations within one txn must be on different keys — the server rejects duplicate writes upfront in txn.go::checkIntervals.

Cross-references

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Transactions – etcd wiki | Factory