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

最佳答案

如果您指的是语法嵌套,那么答案就在于它取决于内部dosync是否将在与外部dosync相同的线程上运行。

在Clojure中,每当输入dosync块时,如果尚未在该线程上运行新事务,则将启动新事务。这意味着,虽然执行停留在单个线程上,但是内部事务可以说是由外部事务所包含的。但是,如果dosync在语法上嵌套在另一个:foo中的位置,但恰好在新线程上启动,则它本身将具有新的事务。

一个(希望)说明发生了什么的示例:

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


打印r后,“内部”事务重试; “外部”事务永远不需要重新启动。 (请注意,在这种情况发生后,dosync的历史链会增长,因此,如果第二次评估“大” dosync表单,则内部的不会重试。它仍然不会合并当然是进入外部。)

顺便说一句,马克·沃尔克曼(Mark Volkmann)在Clojure的Software Transactional Memory上写了一篇很棒的文章。强烈建议对有兴趣深入了解此类详细信息的任何人阅读。

关于clojure - 嵌套的dosync调用的行为如何?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2841750/

10-10 12:43