在Clojure stm的竞争条件?

时间:2015-02-01 11:51:23

标签: clojure race-condition stm

您好我正在阅读本书的快乐,并且在关于STM的部分中,他们有2个事务的图像,其中A最初从参考中检索与B相同的值,然后事务A和B都进行计算但是A首先完成并提交变量,因此B必须重试。

但我正在思考的是B是否会重审A的提交。如果是这样的话那么如果相反呢?那么最终的价值将明显不同。

这似乎很容易被忽视,我相信我完全不理解它。请帮我解开这个。

1 个答案:

答案 0 :(得分:6)

让我们看看例子:

(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))

这里我们有2个事务函数 - 将x增加1并将x乘以2.我们并行应用20个这样的函数(每种函数10个)并观察{{1}的最终值}。实际上每次运行的结果都不同:

ref

实际上这是正确的行为。 STM保证代码将在没有锁的情况下执行,并且以原子方式应用更改(它们不能仅部分应用)。但是,它并不能保证我们对不同的交易顺序会有相同的结果。

Clojure提供了很棒的并行编程工具,可以简化大量正确代码的编写。但是避免这种竞争条件是开发人员的责任(事实上,这种情况显然是系统设计不良的标志)。

SQL的另一个例子:

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

如果这些查询是并行执行的,那么无论什么隔离级别将用于事务 - 结果将取决于订单。