私はclojure.org/refsでそれを読みました
Ref のすべての読み取りでは、トランザクションの開始点 (その「読み取りポイント」) での「Ref world」の一貫したスナップショットが表示されます。トランザクションには、行った変更が表示されます。これはイントランザクション値と呼ばれます。
ウィキペディアのスナップショット分離へのリンクもあります。これは、トランザクションが開始されると、任意の数の参照の読み取りが互いに一貫していることを意味します。
テストケースを作った...
(def r1 (ref 0))
(def r2 (ref 0))
(defn delay-then-inc-ref [id ref delay]
(.start
(Thread.
#((println id " start")
(Thread/sleep delay)
(dosync
(alter ref inc))
(println id " end")))))
(defn deref-delay-deref [ref1 ref2 delay]
(.start
(Thread.
#((println "S start")
(dosync
(let [a @ref2]
(Thread/sleep delay)
(println "S r1=" @ref1))) ; @ref1 consistent with @ref2 ?
(println "S end")))))
*clojure-version*
;=> {:major 1, :minor 3, :incremental 0, :qualifier nil}
(deref-delay-deref r1 r2 2000)
(delay-then-inc-ref "1" r1 500)
(delay-then-inc-ref "2" r1 1000)
(delay-then-inc-ref "3" r1 1500)
出力は次のとおりです。
S start
1 start
2 start
3 start
1 end
2 end
3 end
r1 = 3
S end
nil
not の値は、 r1 = 3
ref1の deref でが 3 つのトランザクションが発生した後に r1 の値を選択してr1 = 0
いることを示唆しています。deref-delay-deref
sleep
delay-then-inc-ref
ensure
特定のトランザクション中に他のトランザクションによる参照への更新を防ぐことについては知っていますが、ここでは当てはまらないと思います。ref1
トランザクションの開始と一致する値が表示される限り、変更されても気にしません。
この動作は、上記の参照ドキュメントにどのように適合しますか?