Skip to content

Document transaction read-your-own-writes semantics + safe concurrent-write patterns (read-back-to-decide is unsafe) #531

Description

@kriszyp

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.

Activity

  1. added
    content📝 Content specific issues and requests - text, examples, missing info, or clarity
    on Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    content📝 Content specific issues and requests - text, examples, missing info, or clarity

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions