嵌套 dosync 调用的行为如何?
创建嵌套 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您指的是语法嵌套,那么答案是这取决于内部
dosync
是否与外部线程在同一线程上运行。在 Clojure 中,只要输入
dosync
块,就会启动一个新事务(如果该线程尚未运行)。这意味着虽然执行停留在单个线程上,但内部事务可以说被外部事务包含;然而,如果一个dosync
占据了语法上嵌套在另一个dosync
中的位置,但碰巧在一个新线程上启动,它本身就会有一个新事务。一个(希望)说明发生情况的示例:
“内部”事务在打印
: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 adosync
occupies a position syntactically nested within anotherdosync
, but happens to be launched on a new thread, it will have a new transaction to itself.An example which (hopefully) illustrates what happens:
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 innerdosync
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.