创建嵌套的 dosync 调用时会发生什么?子事务会在父范围内完成吗?如果父事务失败,这些子事务是否可逆?
问问题
1352 次
1 回答
18
如果您的意思是语法嵌套,那么答案是取决于内部是否dosync
与外部运行在同一线程上。
在 Clojure 中,每当dosync
输入一个块时,如果该线程上尚未运行一个新事务,则会启动一个新事务。这意味着虽然执行停留在单个线程上,但内部事务可以说被外部事务包含;但是,如果 adosync
占据了在语法上嵌套在 another中的位置dosync
,但恰好是在新线程上启动的,则它自身将有一个新事务。
一个(希望)说明发生了什么的例子:
user> (def r (ref 0))
#'user/r
user> (dosync (future (dosync (Thread/sleep 50) (println :foo) (alter r inc)))
(println :bar)
(alter r inc))
:bar
:foo
:foo
1
user> @r
2
“内部”事务在打印后重试:foo
;“外部”事务永远不需要重新启动。(请注意,发生这种情况后,的历史链会增长,因此如果第二次评估r
“大”表单,则内部不会重试。当然,它仍然不会合并到外部。)dosync
dosync
顺便说一句,Mark Volkmann 写了一篇关于 Clojure 的软件事务内存的精彩文章;强烈推荐任何有兴趣深入了解此类细节的人阅读。
于 2010-05-16T01:13:02.463 回答