嵌套 dosync 调用的行为如何?

发布于 2024-09-02 07:51:39 字数 60 浏览 3 评论 0原文

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

What happens when you create nested dosync calls? Will sub-transactions be completed in the parent scope? Are these sub-transactions reversible if the parent transaction fails?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

原来分手还会想你 2024-09-09 07:51:39

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

在 Clojure 中,只要输入 dosync 块,就会启动一个新事务(如果该线程尚未运行)。这意味着虽然执行停留在单个线程上,但内部事务可以说被外部事务包含;然而,如果一个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 不会重试。当然,它仍然不会合并到外部。)顺便

说一句,Mark Volkmann 写了一篇关于 Clojure 的精彩文章 软件事务内存;强烈建议任何有兴趣深入了解此类细节的人阅读此书。

If you mean syntactic nesting, then the answer is it depends on whether the inner dosync will run on the same thread as the outer one.

In Clojure, whenever a dosync block is entered, a new transaction is started if one hasn't been running already on this thread. This means that while execution stays on a single thread, inner transactions can be said to be subsumed by outer transactions; however if a dosync occupies a position syntactically nested within another dosync, but happens to be launched on a new thread, it will have a new transaction to itself.

An example which (hopefully) illustrates what happens:

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

The "inner" transaction retries after printing :foo; the "outer" transaction never needs to restart. (Note that after this happens, r's history chain is grown, so if the "large" dosync form were evaluated for a second time, the inner dosync would not retry. It still wouldn't be merged into the outer one, of course.)

Incidentally, Mark Volkmann has written a fantastic article on Clojure's Software Transactional Memory; it's highly recommended reading for anyone interested in gaining solid insight into details of this sort.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文