嵌套的dosync调用如何表现?

时间:2010-05-15 21:04:01

标签: clojure

创建嵌套dosync调用时会发生什么?子事务是否会在父范围内完成?如果父事务失败,这些子事务是否可逆?

1 个答案:

答案 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的精彩文章;对于有兴趣深入了解此类细节的人,强烈建议阅读。