Summary
Document Harper v5's within-transaction read visibility and the safe concurrent-write patterns. Exploratory QA found a real footgun that is a documentation/guidance gap (committed data is always correct — this is about in-request reads and concurrency patterns, not data corruption).
What to document
1. Within-transaction read-your-own-writes / snapshot semantics
- A FRESH read in a subsequent request (and SQL reads) always reflect committed writes on both engines — committed data is correct.
- WITHIN the same open request transaction: a table-level read-back (
tables.X.get(id), put()-then-get(), addTo-then-refetch) returns the start-of-transaction snapshot on LMDB (it does NOT see the pending write), whereas RocksDB sees the pending write. The loaded resource instance's own this.get() is fresh on both engines.
- Guidance: don't rely on a table refetch within the same transaction to observe your own pending write (especially on LMDB); use
this.get() or re-read after the transaction.
2. Safe concurrent-write primitives (the practical guidance customers need)
- Atomic deltas (
addTo/subtractFrom) are the only primitive whose committed aggregate is exact under concurrency — model concurrent counters as commutative deltas.
- "Write-then-read-the-value-back-to-decide" (rate limiters, claims, state-machine gates) is unsafe under concurrency on both engines (the read-back is not a reliable serialized position; severe on LMDB).
addTo returns no value, so there's no read-your-position.
- For non-commutative correctness (exactly-once claim, admit-only-N, don't-go-below-zero): either serialize through a single writer / external lock, or use the async pattern that DOES work in-Harper — each claimant writes its own non-contended row, use
addTo only to count, and let a single-reader sweep over committed state pick the winner.
Source
Exploratory QA campaign (qa-explorer), scenarios QA-099/100/101/103/104/105/106. Harper 001bf7b9c (v5.1.0). Reference tests in integrationTests/qa-scratch/ (raw-visibility, rate-limiter, cas-audit, claim-recipe, inventory-oversell). Engineering-side tracking of the underlying primitive behavior is in harper#1288 + the read-back/visibility findings.
Summary
Document Harper v5's within-transaction read visibility and the safe concurrent-write patterns. Exploratory QA found a real footgun that is a documentation/guidance gap (committed data is always correct — this is about in-request reads and concurrency patterns, not data corruption).
What to document
1. Within-transaction read-your-own-writes / snapshot semantics
tables.X.get(id),put()-then-get(),addTo-then-refetch) returns the start-of-transaction snapshot on LMDB (it does NOT see the pending write), whereas RocksDB sees the pending write. The loaded resource instance's ownthis.get()is fresh on both engines.this.get()or re-read after the transaction.2. Safe concurrent-write primitives (the practical guidance customers need)
addTo/subtractFrom) are the only primitive whose committed aggregate is exact under concurrency — model concurrent counters as commutative deltas.addToreturns no value, so there's no read-your-position.addToonly to count, and let a single-reader sweep over committed state pick the winner.Source
Exploratory QA campaign (qa-explorer), scenarios QA-099/100/101/103/104/105/106. Harper
001bf7b9c(v5.1.0). Reference tests inintegrationTests/qa-scratch/(raw-visibility,rate-limiter,cas-audit,claim-recipe,inventory-oversell). Engineering-side tracking of the underlying primitive behavior is in harper#1288 + the read-back/visibility findings.