【问题标题】:Clojure: commute before alter within one transaction causes the transaction to failClojure:在一个事务中更改之前通勤导致事务失败
【发布时间】:2017-02-15 12:01:08
【问题描述】:

我是 Clojure 的新手,一直在尝试了解它的事务模型。 在使用altercommute 时,我注意到如果我在alter 后面加上commute 的引用,那么事务将不会提交任何内容(或不会对任何内容进行任何更改)。

例如:

(def counter (ref 0))
(def i (ref 0))
(future (dosync
          (ref-set counter 1)
          (ref-set i 1)
          (commute counter inc)
          (alter counter inc)))

@counter@i 都将为 0,但如果我交换 commutealter 或在这种情况下使用两个 commutes 或两个 alters,它将产生所需的结果(3和 1)。

我读过一些帖子,解释commutealter 的行为有点不同,因为commute 实际上在事务中执行了两次(一个在它所在的位置,另一个在“提交”阶段)并忽略参考的不一致快照。我只是对这两者组合的奇怪行为感到困惑。

谁能帮忙解释一下它是如何工作的?提前致谢!

【问题讨论】:

  • clojure 1.8:它在 repl {:status :failed, :val #error { :cause "Can't set after commute" :via [{:type java.util.concurrent.ExecutionException ... 中输出,所以不要在 commute 之后使用 alter。找不到任何特定的文档 - 只是 source

标签: clojure transactions stm


【解决方案1】:

commute 函数仅在非常狭窄(即罕见)的情况下有用,在这种情况下它可能以额外重试更新功能。正如您的示例所示,它还使交易的心理模型变得更加复杂(例如,我以前从未见过这个特殊问题)。

恕我直言,使用alter 而不是commute 几乎总是更好,因为alter 更简单且更防弹。事实上,我通常会认为使用commute 是一种过早优化

【讨论】:

    猜你喜欢
    • 2020-07-05
    • 1970-01-01
    • 2017-07-04
    • 2015-10-25
    • 2014-10-04
    • 2021-12-13
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多