简体   繁体   English

在Clojure stm的竞争条件?

[英]Race condition in Clojure stm?

Hello I was reading the book joy of clojure and in the section about the STM they have an image of 2 transactions where A is initially retrieving the same value from a ref as B is and then both transaction A and B does their calculations but A finishes first and makes the commit to the variable and thus B must retry. 您好我正在阅读本书的快乐,并且在关于STM的部分中,他们有2个交易的图像,其中A最初从参考中检索与B相同的值,然后事务A和B都进行计算但是A完成首先,提交变量,因此B必须重试。

But what I am pondering about is if B would have retried with A's commit. 但我正在思考的是,B是否会重复A的提交。 And if that is the case then what if it where the opposite? 如果是这样的话那么如果相反呢? Then the final value would be significally different. 那么最终的价值将明显不同。

This seems to simple of a hazard to have been overlooked,and I believe I don't understand it completely. 这似乎很容易被忽视,我相信我完全不理解它。 Please help me untangle this. 请帮我解开这个。

Let's look at example: 我们来看看例子:

(defn test-trans []
  (let [x (ref 1)
        t-inc #(dosync (alter x inc))
        t-mul #(dosync (alter x (partial * 2)))
        fns (flatten (repeat 10 [t-mul t-inc]))]
    (last (pmap (fn [f] (f)) fns))
    @x))

Here we have 2 transactional functions - increase x by 1 and multiply x by 2. We apply 20 such functions (10 of each kind) in parallel and observe final value of ref . 这里我们有2个事务函数 - 将x增加1并将x乘以2.我们并行应用20个这样的函数(每种函数10个)并观察ref最终值。 Indeed results are different for each run: 实际上每次运行的结果都不同:

=> (test-trans)
2418
=> (test-trans)
2380
=> (test-trans)
1804
=> (test-trans)
4210

Actually this is correct behaviour. 实际上这是正确的行为。 STM guarantees that code will be executed without locks and changes are applied atomically (they cannot be applied only partially). STM保证代码将在没有锁的情况下执行,并且以原子方式应用更改(它们不能仅部分应用)。 However it does not guarantee that we will have the same result for different order of transactions. 但是,它并不能保证我们对不同的交易顺序会有相同的结果。

Clojure provides great parallel programming instruments which simplify writing of correct code a lot. Clojure提供了很好的并行编程工具,可以简化正确的代码编写。 But avoiding this kind of race conditions is responsibility of developer (in fact, such cases are clear sign of bad system design). 但是避免这种竞争条件是开发人员的责任(实际上,这种情况是系统设计不良的明显迹象)。

Another example from SQL: SQL的另一个例子:

DELETE FROM tbl WHERE col=1
UPDATE tbl SET col=2 WHERE col=1

If these queries are executed in parallel, then no matter what isolation level will be used for transactions - result will depend on the order. 如果这些查询是并行执行的,那么无论什么隔离级别将用于事务 - 结果将取决于顺序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM