Available now (0.4):
- MVCC — each write creates a new version; readers see a consistent snapshot without blocking writers
- Snapshot isolation — a transaction reads the database as of its start timestamp; its own writes are visible to itself before commit
- Serializable (SSI) — opt-in read-set validation under the
serializablefeature, rejecting write skew and the read-only anomaly - Durable commit log — under the
durabilityfeature,Db::openlogs each commit to awal-dbwrite-ahead log and syncs before acknowledging; the log is replayed on restart - Write-write conflict detection — first-committer-wins at commit; the later writer is told to retry with a typed, retryable error
- Sharded commit path — lock-free timestamp allocation and per-shard conflict checks, so commits to unrelated keys do not contend (loom-checked)
- Pluggable backing store — the version store is the
VersionStoretrait; an in-memory store ships, and any backend plugs in
On the roadmap:
- Garbage collection — old versions reclaimed once no live snapshot can observe them
- Backing-store integration — compose over
lsm-dbor any store through the trait
Installation
[]
= "0.4"
# Opt into serializable isolation and/or a durable commit log:
= { = "0.4", = ["serializable", "durability"] }
Quick start
The whole common case is begin, read and write through the transaction, commit:
use Db;
let db = new;
// Write two keys in one atomic transaction.
let mut tx = db.begin;
tx.put;
tx.put;
tx.commit?;
// A later transaction reads a consistent snapshot.
let tx = db.begin;
assert_eq!;
# Ok::
When two transactions race to write the same key, the first to commit wins and the second is told to retry — that is what prevents lost updates:
use Db;
let db = new;
let mut a = db.begin;
let mut b = db.begin;
a.put;
b.put;
a.commit?; // first committer wins
let err = b.commit.unwrap_err; // second is rejected
assert!; // retry against the fresh snapshot
# Ok::
The retry loop is a few lines; see examples/concurrent_counter.rs
for the contended read-modify-write pattern, examples/bank_transfer.rs
for an atomic multi-key transfer, and examples/custom_store.rs
for plugging in your own VersionStore.
Serializable isolation
Snapshot isolation still allows write skew: two transactions that read the same
rows and write different ones can both commit, breaking an invariant that ties
those rows together. With the serializable feature,
begin_serializable validates a transaction's read set
at commit and rejects exactly those cases.
#
#
# Ok::
See examples/serializable_doctors.rs for the
full on-call-doctors demonstration, side by side under both isolation levels.
Durability
With the durability feature, Db::open backs the database with a wal-db
write-ahead log. Each commit's record is appended and synced before commit
returns, so an acknowledged commit survives a crash; on restart the log is
replayed and uncommitted work leaves no trace.
#
#
# Ok::
See examples/durable_store.rs for a commit /
drop / reopen walkthrough.
Examples
| Example | What it shows |
|---|---|
quick_start |
Shortest end-to-end: open, write, read back. |
bank_transfer |
Atomic multi-key update with conflict retries. |
concurrent_counter |
Many threads increment one key; no update is lost. |
snapshot_reads |
A snapshot stays stable as the database moves on. |
custom_store |
Backing the engine with a custom VersionStore. |
serializable_doctors |
Write skew under SI vs serializable (needs --features serializable). |
durable_store |
Commit, drop, reopen — recovery from the log (needs --features durability). |
Status
This is the 0.4 release: the MVCC core, snapshot and serializable isolation,
and a sharded lock-free commit path, now with a durable commit log via wal-db
(the durability feature) and log replay on restart. The
docs/API.md reference documents the full Tier-1 surface, and
the remaining phases — version garbage collection and backing-store integration
— follow per the roadmap. The shape of the Tier-1 API is settled and will not
change before 1.0.
Where It Fits
txn-db is the transaction layer. It builds on:
wal-db— durable transaction commit loglsm-db— a natural backing version store- Hive DB — the transaction orchestration layer (DISTRO) builds on these semantics
It stays foreign-compatible: usable standalone over any version store that implements the trait.
Contributing
Before opening a PR, cargo fmt --all, cargo clippy --all-targets --all-features -- -D warnings, and cargo test --all-features must be clean. Hot-path changes require a criterion benchmark; correctness-critical paths require property and/or loom tests.