- Lock modes — the five standard multi-granularity modes — intention-shared (IS), intention-exclusive (IX), shared (S), shared-intention-exclusive (SIX), and exclusive (X) — with a
constcompatibility matrix at the core of every grant decision - Hierarchical granularities — lock a database / table / page / row hierarchy correctly with intention locks; the manager enforces the matrix at every level
- Range locks — lock a contiguous span of keys (
KeyRange) for predicate / phantom protection, with overlap-based conflict detection - Deadlock detection — a wait-for graph with cycle detection and victim selection; the deadlock-aware
requestrecords waits and reports cycles, andWaitForGraphis reusable on its own - Sharded lock table — the resource space is partitioned across independent shards so acquisitions on unrelated resources never contend on the same mutex
- Acquire / release — non-blocking
try_acquire, single and bulk release, re-entrant acquisition, and lattice upgrades (e.g. S + IX → SIX)
Installation
[]
= "0.4"
Quick Start
use *;
// One manager, shared across all worker threads behind an `Arc`.
let lm = new;
let row = new;
let = ;
// The writer takes the row exclusively.
lm.try_acquire.unwrap;
// A concurrent reader is refused while the write lock is held.
assert_eq!;
// Once the writer commits and releases, the reader gets in.
lm.release.unwrap;
lm.try_acquire.unwrap;
Range-lock a span of keys to keep another transaction from inserting into it (phantom protection):
use *;
let lm = new;
let index = new; // the key space being protected
// Txn 1 read-locks keys [100, 200].
lm.try_acquire_range.unwrap;
// Txn 2 cannot write key 150 inside that range, but a disjoint range is free.
assert!;
lm.try_acquire_range.unwrap;
A transaction drops its whole lock set — point and range — in one call at commit or abort:
use *;
let lm = new;
let txn = new;
for id in 0..3
assert_eq!;
The deadlock-aware request records waits and reports cycles, naming a victim to
abort:
use *;
let lm = new;
let = ;
let = ;
lm.request; // T1 holds A
lm.request; // T2 holds B
lm.request; // T1 waits for T2
// T2 waiting for A closes the cycle; abort the victim to break it.
if let Deadlock = lm.request
API Overview
For the complete reference with method tables and examples, see docs/API.md.
LockMode— the five MGL modes and the compatibility matrixLockManager— the sharded lock table (point locks, range locks, deadlock-awarerequest)WaitForGraph— wait-for graph, cycle detection, and victim selectionKeyRange— an inclusive key interval for range locksTxnIdandResourceId— opaque identifiersLockError— failure modes
Examples
Runnable examples live in examples/. Run any of them with
cargo run --example <name>:
| Example | Shows |
|---|---|
quick_start |
Acquire, conflict, release on a single row. |
two_phase_locking |
Growing-phase acquires, then release_all at commit. |
shared_upgrade |
Read under a shared lock, then upgrade to exclusive. |
hierarchy |
Intention locks over a database/table/page/row hierarchy. |
range_locks |
Range locking for phantom protection. |
deadlock |
Wait-for deadlock detection and victim abort. |
concurrent |
Many threads contending on one row, with a mutual-exclusion check. |
Where It Fits
lock-db is the concurrency-control layer. It is used by:
txn-db— transactions acquire and release locks here to enforce isolationpage-db— page-granularity locks coordinate with the paged storeindex-db— range locks protect B+tree key ranges against phantoms- storage engines — any engine needing pessimistic concurrency control
It has no first-party dependencies, so it builds and tests standalone today.
Cross-Platform Support
Linux (x86_64, aarch64), macOS (x86_64, Apple Silicon), and Windows (x86_64) are first-class and verified by the CI matrix.
Contributing
See CONTRIBUTING.md and dev/DIRECTIVES.md. Before a PR: cargo fmt --all, cargo clippy --all-targets --all-features -- -D warnings, and cargo test --all-features must be clean.