如何在clojure中让长时间运行的事务快速失败

如何在clojure中让长时间运行的事务快速失败,clojure,stm,Clojure,Stm,假设以下代码中的ref在其他事务以及下面的事务中被修改, 我担心的是,该事务将一直运行到提交时间,提交失败,然后重新运行该事务 (defn modify-ref [my-ref] (dosync (if (some-prop-of-ref-true @my-ref) (alter my-ref long-running-calculation)))) 以下是我的全部恐惧: 调用modify ref,启动事务(称为a),并启动长时间运行的计算 另一个事务(称为B)启动

假设以下代码中的ref在其他事务以及下面的事务中被修改, 我担心的是,该事务将一直运行到提交时间,提交失败,然后重新运行该事务

(defn modify-ref [my-ref]
  (dosync (if (some-prop-of-ref-true @my-ref)
            (alter my-ref long-running-calculation))))
以下是我的全部恐惧:

  • 调用modify ref,启动事务(称为a),并启动长时间运行的计算
  • 另一个事务(称为B)启动、修改我的ref并返回(提交成功)
  • 长时间运行的计算将继续进行,直到完成为止
  • 事务A尝试提交,但由于my ref已被修改而失败
  • 事务将使用my ref的新值重新启动(称为A'),并退出,因为某些属性不正确
  • 这是我希望发生的事情,也许这就是发生的事情(我只是不知道,所以我要问的问题是:-)

    当事务B提交my ref时,我希望事务A立即停止(因为my ref的值已更改),并使用新值重新启动。是这样吗

    我想要这种行为的原因是,长时间运行的计算不会将所有CPU时间浪费在现在已经过时的计算上

    我曾考虑过使用
    确保
    ,但我不确定在这种情况下如何使用它,或者是否有必要使用它。

    它会像你担心的那样工作

    停止JVM中的线程执行它正在执行的任何操作都需要协作,因此Clojure(或任何其他JVM语言)没有通用的方法来停止正在运行的计算。计算必须周期性地检查一个信号,看它是否应该自行停止。看

    关于如何实现它,我会说这太难了,所以我会首先衡量它是否真的是一个问题。如果是的话,我会看看传统的解决方案是否更好。如果悲观锁仍然不是解决方案,我会尝试构建一些在事务之外运行计算的东西,在refs上使用,并在计算之后有条件地设置refs(如果它们仍然具有相同的值)。当然,这超出了事务边界,而且听起来可能要复杂得多

    关于
    确保
    ,只有正在修改的引用才会参与事务,因此您可能会受到影响。请参阅以获得更详细的解释。

    它在你害怕的时候起作用

    停止JVM中的线程执行它正在执行的任何操作都需要协作,因此Clojure(或任何其他JVM语言)没有通用的方法来停止正在运行的计算。计算必须周期性地检查一个信号,看它是否应该自行停止。看

    关于如何实现它,我会说这太难了,所以我会首先衡量它是否真的是一个问题。如果是的话,我会看看传统的解决方案是否更好。如果悲观锁仍然不是解决方案,我会尝试构建一些在事务之外运行计算的东西,在refs上使用,并在计算之后有条件地设置refs(如果它们仍然具有相同的值)。当然,这超出了事务边界,而且听起来可能要复杂得多


    关于
    确保
    ,只有正在修改的引用才会参与事务,因此您可能会受到影响。请参阅以获得更详细的解释。

    这不会发生,因为……嗯,怎么可能?您的函数
    长时间运行的计算
    中没有任何代码可以处理提前停止,这就是您要取消事务时正在运行的代码。因此,停止它的唯一方法是先停止线程的执行,然后在其他位置强制重新启动它。这是非常危险的,正如java 1.1中发现的java.lang.Tread/stop;副作用可能比浪费CPU周期更严重


    refs确实试图解决这个问题,sorta:如果有一个长时间运行的事务因为短时间的事务不断潜入而不得不多次重新启动自身,那么它将需要一个更强大的锁并运行到完成。但这是一种非常罕见的情况(见鬼,即使需要使用REF也是很罕见的,而且REF的行为方式也很少见)。

    这不会发生,因为……好吧,怎么可能呢?您的函数
    长时间运行的计算
    中没有任何代码可以处理提前停止,这就是您要取消事务时正在运行的代码。因此,停止它的唯一方法是先停止线程的执行,然后在其他位置强制重新启动它。这是非常危险的,正如java 1.1中发现的java.lang.Tread/stop;副作用可能比浪费CPU周期更严重


    refs确实试图解决这个问题,sorta:如果有一个长时间运行的事务因为短时间的事务不断潜入而不得不多次重新启动自身,那么它将需要一个更强大的锁并运行到完成。但这是一种非常罕见的情况(见鬼,即使需要使用ref也是罕见的,而且ref的行为方式也是罕见的)。

    这是在询问事务何时提交,其他涉及任何ref的挂起事务是否会立即取消?这是问问问事务何时提交,其他挂起的事务是否涉及立即取消的事务更改?我发现您的回答中有几句话很有启发性,也很有用(例如,关于“如果有一个长时间运行的话”)。然而,我发现第一句话令人困惑:“这没有发生,因为……好吧,怎么可能呢?”。什么事没有发生?我发现你的回答中有几句话很有启发性,也很有用(例如,关于“如果有一个长期运行的话”)。然而,我发现第一句话令人困惑:“这没有发生,因为……好吧,怎么可能呢?”。什么事没有发生?如果那样的话,我会投这个票