Table of Contents

Conflict resolution

In one line: the write side of MVCC — Typhon takes no write locks, so a write-write conflict is detected at commit, and you choose the outcome: silent last-writer-wins, or a handler that reconciles.

Snapshot isolation explains why reads never block; this is the other half. Because a transaction locks nothing while it runs, two transactions can read the same entity and both intend to write it. At Commit, each written entity is checked against a monotonic per-entity commit counter: if someone committed a newer value since your snapshot, that entity conflicts. The plain Commit() doesn't look — the committing value simply overwrites (last-writer-wins), silently discarding the other transaction's work. Fine for a position; dangerous for a counter, a balance, or an accumulator.

Pass a ConcurrencyConflictHandler to Commit(handler) and you decide, per conflicting entity. The engine populates a ConcurrencyConflictSolver with three views of the entity — what you read, what was committed underneath you, and what you're committing — and invokes your handler once for that entity, under the entity's revision-chain lock, so detection and resolution are one atomic step no other writer can interleave. Your handler picks TakeRead (drop your change), TakeCommitted (accept theirs), TakeCommitting (keep yours — the default), or writes a custom value into ToCommitData to rebase / merge / clamp. There is no abort path — a handler chooses the value that commits, it cannot fail the commit.

⚠️ Versioned only. Detection needs a revision chain to compare against, so it applies to Versioned components; SingleVersion / Committed / Transient are last-writer-wins by construction — there is no prior revision to reconcile. Handlers run under a lock on the commit path — keep them fast and allocation-light (no I/O, no calls back into the engine).

How it relates

  • Snapshot isolation — the read side; this is the write side of the same optimistic model.
  • Transaction — conflicts are detected and resolved during its Commit.
  • Storage mode — only Versioned participates; the fast modes clobber.
  • Unit of Work — the durability boundary a resolved commit lands in.

In the API

Learn & use