Skip to main content

Module txn

Module txn 

Source
Expand description

Transaction layer (L7).

Wraps the Pager + cross-process file locks + reader snapshots into a write- / read-transaction abstraction. Single-writer model: a WriteTxn holds (a) the in-process write- serialization gate on the pager-shared TxnEnv and (b) the cross-process WRITER_LOCK byte (when the env was constructed with a lock file). ReadTxn holds a shared reader lock byte and a ReaderSnapshot; readers do not contend with each other and do not block writers.

This module exposes the building blocks; M6 issue #47 wraps the result as obj::Db.

§In-process write-serialization gate (issue #18)

The gate is an AtomicBool behind an Arc, NOT a Mutex<()>. An acquired WriteSerialGuard OWNS a clone of that Arc and, on Drop, store(false, Release)s the flag. Because the guard owns the Arc (rather than borrowing the env), it is Send + 'static, which in turn makes WriteTxn Send — letting the obj-py binding release the GIL across the blocking lock-acquire.

No poisoning (deliberate, and strictly better). A Mutex<()> poisons if a thread panics while holding the guard, turning every subsequent WriteTxn::begin into a permanent Busy{WriterInProcess}. The AtomicBool gate has no such state: if a writer panics mid-transaction, unwinding drops the WriteTxn (whose Drop rolls back — restoring header_at_begin so the pager is left at consistent committed state) and then drops the WriteSerialGuard (which releases the gate). The next writer proceeds against that consistent state. This replaces a permanent-Busy failure mode with a recover-and-continue one.

§Power-of-ten posture

  • Rule 4. Public methods on WriteTxn / ReadTxn are short delegations to the pager.
  • Rule 5. WriteTxn::commit flips an internal committed flag before draining the txn so a subsequent Drop on a committed txn cannot roll back; the flag is debug-asserted in the Drop impl.
  • Rule 7. No unwrap / expect in production paths. A poisoned pager mutex surfaces as Error::Busy with LockKind::WriterInProcess rather than a panic; the gate itself cannot poison.
  • Rule 9. No dynWriteTxn<'db, F: FileBackend> and ReadTxn<'db, F: FileBackend> are monomorphised.

Structs§

ReadTxn
A read transaction.
TxnEnv
Environment shared by every WriteTxn / ReadTxn in a process. Holds the pager (behind an Arc<Mutex<_>>), the in- process write-serialization mutex, and — for file-backed databases — an optional FileHandle used for cross-process byte-range locking.
WriteAcquire
A Send token holding BOTH blocking-acquired write locks, with no borrow of the env.
WriteSerialGuard
RAII guard on the in-process write-serialization gate.
WriteTxn
A write transaction.

Constants§

DEFAULT_BUSY_TIMEOUT
Default busy timeout for WriteTxn::begin and ReadTxn::begin when the caller does not pass a per-call deadline. 5 seconds matches SQLite’s default and the design.md Config::busy_timeout proposal.