liveBook · Manning

Read fault

As explained in Clojure: The Essential Reference

A read fault is a transactional memory condition in which a transaction cannot safely use the value it read and must respond according to the ref's history policy.

A read fault occurs when a transaction tries to use a stale ref value. The STM rejects that read and restarts the transaction so it can observe the current committed value. section 14.4

Read-fault behavior depends on the ref’s history policy:

  • With the default zero history, a slow reader cannot use a value overwritten before its read completes; the transaction retries. section 14.4
  • With positive min-history, a ref can retain in-transaction values and tolerate some stale reads without restarting. section 14.4
  • ref-min-history configures this tolerance, while ref-max-history limits how many values the ref stores. section 14.4

A slow reader retries

A transaction T1 reads ref r, sleeps, and then encounters a value committed by faster transaction T2. With the default history, T1 starts twice and ultimately returns 1 rather than stale value 0. Setting :min-history 1 allows the reader to return 0 while r has become 1. section 14.4

(let [r (ref 0)   ; #1
      T1 (future  ; #2
           (dosync
             (println "T1 starts")
             (Thread/sleep 1000)
             (println "T1 history-count"
               (ref-history-count r))
             @r))
      T2 (future
           (dosync
             (println "T2 starts")
             (alter r inc)))] ; #3
  [@T1 @T2 @r])

;; T1 starts
;; T2 starts
;; T1 history-count 0 ; #4
;; T1 starts          ; #5
;; T1 history-count 0
;; [1 1 1]

Inspect the concurrent futures example to see the retry in its printed output. section 14.4

How Clojure: The Essential Reference covers it

How deep it goes
Explains stale-value detection, automatic retries, and ref-history configuration through concurrent examples.
Examples
Uses slow-reader and fast-writer futures, printed retries, and min-history comparisons.
What it assumes
Assumes familiarity with Clojure refs, dosync, concurrent transactions, and committed values.
What you can do after
Diagnose transaction retries and configure tolerated stale reads with ref-min-history.
How it connects
Connects transactional memory, STM transactions, refs, stale reads, and ref history.

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.