我有以下代码
(def number (ref 0))
(dosync (future (alter number inc))) ; A
(future (dosync (alter number inc))) ; B
第二个成功,但第一个失败了no transaction is running
。但它包含在dosync中吗?
clojure是否记得根据创建的线程打开事务?
答案 0 :(得分:2)
你是对的。 public ngAfterViewInit(): void {
this.accountForm.valueChanges.subscribe(() => {
this.displayMessage = this.genericValidator.processMessages(this.accountForm);
});
}
的整个目的是在当前线程中开始一个事务。 dosync
在新线程中运行其代码,因此案例A中的future
不在其线程的alter
内。
对于案例B,dosync
和alter
都在同一个(新)线程中,因此没有问题。
答案 1 :(得分:2)
这有多种原因无法奏效。正如Alan Thompson写的那样,交易归属于单个线程,因此当您创建新线程时,您将丢失交易。
另一个问题是dosync
的动态范围。如果你写了
((dosync #(alter number inc)))
这里我们在dosync
范围内创建一个函数,让该函数成为dosync
的结果。然后我们从dosync
块之外调用该函数,但当然事务不再运行。
这与您使用future
非常相似:future
创建一个函数,然后在新线程上执行它,返回一个可用于检查的句柄那个线程的进展。即使允许跨线程事务,您也会遇到竞争条件:dosync
阻止在alter
执行future
之前或之后关闭其事务吗?