[英]Race condition in Clojure stm?
您好我正在阅读本书的快乐,并且在关于STM的部分中,他们有2个交易的图像,其中A最初从参考中检索与B相同的值,然后事务A和B都进行计算但是A完成首先,提交变量,因此B必须重试。
但我正在思考的是,B是否会重复A的提交。 如果是这样的话那么如果相反呢? 那么最终的价值将明显不同。
这似乎很容易被忽视,我相信我完全不理解它。 请帮我解开这个。
我们来看看例子:
(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个)并观察ref
最终值。 实际上每次运行的结果都不同:
=> (test-trans)
2418
=> (test-trans)
2380
=> (test-trans)
1804
=> (test-trans)
4210
实际上这是正确的行为。 STM保证代码将在没有锁的情况下执行,并且以原子方式应用更改(它们不能仅部分应用)。 但是,它并不能保证我们对不同的交易顺序会有相同的结果。
Clojure提供了很好的并行编程工具,可以简化正确的代码编写。 但是避免这种竞争条件是开发人员的责任(实际上,这种情况是系统设计不良的明显迹象)。
SQL的另一个例子:
DELETE FROM tbl WHERE col=1
UPDATE tbl SET col=2 WHERE col=1
如果这些查询是并行执行的,那么无论什么隔离级别将用于事务 - 结果将取决于顺序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.