未来内部的Clojure dosync与dosync中的未来

时间:2017-11-07 16:00:54

标签: clojure stm

我有以下代码

(def number (ref 0))

(dosync (future (alter number inc)))  ; A
(future (dosync (alter number inc)))  ; B

第二个成功,但第一个失败了no transaction is running。但它包含在dosync中吗?

clojure是否记得根据创建的线程打开事务?

2 个答案:

答案 0 :(得分:2)

你是对的。 public ngAfterViewInit(): void { this.accountForm.valueChanges.subscribe(() => { this.displayMessage = this.genericValidator.processMessages(this.accountForm); }); } 的整个目的是在当前线程中开始一个事务。 dosync在新线程中运行其代码,因此案例A中的future不在其线程的alter内。

对于案例B,dosyncalter都在同一个(新)线程中,因此没有问题。

答案 1 :(得分:2)

这有多种原因无法奏效。正如Alan Thompson写的那样,交易归属于单个线程,因此当您创建新线程时,您将丢失交易。

另一个问题是dosync的动态范围。如果你写了

,就会出现同样的问题
((dosync #(alter number inc)))

这里我们在dosync范围内创建一个函数,让该函数成为dosync的结果。然后我们从dosync块之外调用该函数,但当然事务不再运行。

这与您使用future非常相似:future创建一个函数,然后在新线程上执行它,返回一个可用于检查的句柄那个线程的进展。即使允许跨线程事务,您也会遇到竞争条件:dosync阻止在alter执行future之前或之后关闭其事务吗?