创建嵌套dosync调用时会发生什么?子事务是否会在父范围内完成?如果父事务失败,这些子事务是否可逆?
答案 0 :(得分:16)
如果你的意思是句法嵌套,那么答案是它取决于内部dosync
是否会在与外部dosync
相同的线程上运行。
在Clojure中,每当输入dosync
块时,如果尚未在此线程上运行,则启动新事务。这意味着当执行保留在单个线程上时,内部事务可以说是由外部事务包含的;但是如果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
表单,则内部{{1}}将不会重试。当然,仍然不会合并到外部。)
顺便说一下,Mark Volkmann写了一篇关于Clojure Software Transactional Memory的精彩文章;对于有兴趣深入了解此类细节的人,强烈建议阅读。