「Clojure プログラミング」(Emerick、O'Reilly) は次のように述べています。
(...) 現在のトランザクションの開始以降に別のトランザクションによって新しい値がコミットされた場合、トランザクションの開始時点での ref の新しい値は提供できません。幸いなことに、STM はこの問題に気付き、トランザクションに関係する参照の状態の限定された履歴を維持します。履歴のサイズは再試行ごとに増加します。これにより、ある時点でトランザクションを再試行する必要がなくなる可能性が高くなります。これは、ref が同時に更新されている間、目的の値がまだ履歴に存在するためです。
次に、問題を説明するためにいくつかのコード サンプルを示します。
最初に、すべての書き込みトランザクションが完了した後にのみ読み取りトランザクションが成功することを説明します (したがってa = 500
):
(def a (ref 0))
(future (dotimes [_ 500] (dosync (Thread/sleep 20) (alter a inc))))
@(future (dosync (Thread/sleep 1000) @a))
; 500
(ref-history-count a)
; 10
次に、その設定を説明し:min-history
、:max-history
リーダー トランザクションの再試行に役立つ場合があります (今回a
は以前に正常に読み取られました - 値は 33 です)。
(def a (ref 0 :min-history 50 :max-history :100))
(future (dotimes [_ 500] (dosync (Thread/sleep 20) (alter a inc))))
@(future (dosync (Thread/sleep 1000) @a))
; 33
deref
リーダートランザクション内で再試行が発生する理由を理解しています(一部のライタートランザクションが参照への変更をコミットしている場合)。私が理解していないのはこの部分です:「これにより、ある時点でトランザクションを再試行する必要がなくなる可能性が高くなります。これは、参照が同時に更新されている間、目的の値がまだ履歴に存在するためです」.
「望ましい値」とは何ですか?上記の例では、時間の経過とともに参照履歴がどのように変化しますか? 参照履歴がどのように機能するかを示すタイムラインの説明または例を教えてもらえますか?