我有这个代码:
(defn on-thread [f]
(.start (Thread. f)))
(def myref (ref 0))
(on-thread
#(loop [x 100]
(when (> x 0)
(do
(Thread/sleep 100)
(println "myref is:" @myref)
(recur (dec x))))))
(on-thread
#(dosync
(println "transaction1 initial:" @myref)
(alter myref inc)
(println "transaction1 final:" @myref)
(Thread/sleep 5000)
(println "transaction1 done")))
(on-thread
#(dosync
(println "transaction2 initial:" @myref)
(Thread/sleep 1000)
(alter myref inc)
(println "transaction2 final:" @myref)
(println "transaction2 done")))
当我运行它时,很明显第一个事务首先运行,它将 ref 的值更改为 1 - 但其他线程看不到这一点:好吧,当然,因为第一个事务尚未完成。所以我认为此时还没有“提交”给裁判。
但是此时,第一个事务进入睡眠状态,当它处于睡眠状态时,第二个事务尝试更改 ref 的值。它被回滚,并被环境重试!为什么?第二笔交易如何“看到”第一笔交易的 ref 发生了(或将要发生)某事?
我认为如果第二个事务能够更改 ref 的事务中值(从 0 到 1)然后休眠 1000,然后最终成功提交,那么将重试第一个事务会更合乎逻辑. 但这种情况并非如此。
为什么?