4

我正在阅读Programming Clojure这本书。在解释alter和 STM 时,他们说如果在更改期间,Clojure 检测到来自事务外部对 ref 的更改,它将使用新值重新运行事务。如果是这种情况,我会想象您传入的更新函数需要是纯的,但文档中没有说明(并且在其他类似情况下也是如此)。

那么我的假设正确吗?如果不是,STM如何重新应用该功能?如果它是正确的,是不是你不能依靠文档告诉你什么时候可以有副作用,什么时候不能?

4

3 回答 3

8

它不一定是纯的,它只是必须是幂等的。在实践中,这基本上是一样的。

此外,它仅在 STM 之外必须是幂等的:如果您产生的唯一副作用是写入某个其他 ref 或(我认为)发送给代理,则该操作将一直保持到您的事务成功为止。

它也不是必须是这些东西中的任何一个:只是,如果你的更新函数不是纯的,结果可能不是你所期望的。

编辑:dosync的文档告诉您,正文中的任何表达式都可能多次执行。不运行 a就无法alter运行 a dosync,因此看起来您需要的所有文档都在那里。你想改变什么?

于 2011-03-25T02:13:15.120 回答
4

顺便说一句:

如果您需要执行副作用,例如登录您的 STM 事务,您可以向代理发送消息以执行非幂等部分。发送给代理的消息仅在事务完成时发送,并且保证只发送一次。

于 2011-03-25T05:50:08.257 回答
1

Clojure 中的要点是,在处理 Transactions 时没有副作用,因为它们是一致的,并且在更新 Shared Value 过程中发现冲突时,函数会重新运行(我更喜欢重试),否则会成功提交更改。如果它必须重试,它会读取更新的值,所以没有副作用,你可以找到一个活锁的问题,但它是受 Clojure 重试次数限制的控制。

于 2011-12-11T21:51:51.963 回答