软件事务存储的可组合性示例


11

经常被提及的软件事务存储的主要优点之一是可组合性和模块化。可以将不同的片段合并以产生更大的成分。在基于锁的程序中,通常不是这种情况。

我正在寻找一个简单的示例,用实际代码对此进行说明。我希望在Clojure中举一个例子,但是Haskell也很好。如果该示例还展示了一些不易编写的基于锁的代码,则可以加分。


1
有趣,但对我来说听起来更像是一个StackOverflow问题。
史蒂夫

4分钟后在那里问了这个问题。stackoverflow.com/questions/5518546 / ...有人会迁移并合并此问题(如果可能)吗?
工作

是的,在我将其发布到这里之后,我意识到在Stackoverflow上可能会更好。如果有人可以合并,那对我很好。
dbyrne 2011年

Answers:


9

假设您有一些银行帐户:

(def accounts 
 [(ref 0) 
  (ref 10) 
  (ref 20) 
  (ref 30)])

和原子的“转移”功能:

(defn transfer [src-account dest-account amount]
  (dosync
    (alter dest-account + amount)
    (alter src-account - amount)))

其工作原理如下:

(transfer (accounts 1) (accounts 0) 5)

(map deref accounts)
=> (5 5 20 30)

然后,您可以轻松地组合转账功能以创建更高级别的交易,例如从多个帐户转账:

(defn transfer-from-all [src-accounts dest-account amount]
  (dosync
    (doseq [src src-accounts] 
      (transfer src dest-account amount))))

(transfer-from-all 
  [(accounts 0) (accounts 1) (accounts 2)] 
  (accounts 3) 
  5)

(map deref accounts)
=> (0 0 15 45)

请注意,所有多次转帐都发生在单个合并的交易中,即可以“组成”较小的交易。

要使用锁来执行此操作将很快变得很复杂:假设需要分别锁定帐户,则您需要执行一些操作,例如在锁获取顺序上建立协议以避免死锁。犯下难以发现的错误非常容易。STM使您免于所有这些痛苦。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.