STM 和 Clojure 中的更改

发布于 2024-10-27 02:56:24 字数 232 浏览 1 评论 0原文

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

那么我的假设正确吗?如果没有,STM如何重新应用该功能?如果它是正确的,那么您是否不能依赖文档来告诉您何时可以产生副作用,何时不能产生副作用?

I am working through the Programming Clojure book. While explaining alter and the STM, they say that if, during an alter, Clojure detects a change to the ref from outside the transaction, it will re-run the transaction with the new value. If that is the case, I would imagine the update function you pass in needs to be pure, but that isn't indicated in the docs (and it is in other similar situations).

So is my assumption correct? If not, how does the STM re-apply the function? If it is correct, is it the case that you can't rely on the docs to tell you when you can have side effects, and when you can't?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

花期渐远 2024-11-03 02:56:24

它不必严格是纯粹的,它只需幂等即可。实际上,这基本上是同一件事。

此外,当在 STM 外部看到时,它只需是幂等的:如果您产生的唯一副作用是写入其他引用或(我认为)发送到代理,则该操作将被保留,直到您的事务成功为止。

事实上,它也不一定是这些东西:只是,如果您的更新函数不是纯粹的,结果可能不是您所期望的。

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

It doesn't strictly have to be pure, it just has to be idempotent. In practice this is basically the same thing.

Further, it only has to be idempotent when seen outside of the STM: if the only side effect you produce is writing to some other ref or (I think) sending to an agent, that operation will be held until your transaction has succeeded.

It's also not really the case that it has to be any of these things: just that, if your update function isn't pure, the results may not be what you expect.

Edit: dosync's docs tell you that any expressions in the body may be executed more than once. You can't run an alter without running a dosync, so it looks like all the docs you need are there. What would you like changed?

橘和柠 2024-11-03 02:56:24

顺便说一句:

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

Just as a side note:

If you need to perform side-effects like logging in your STM transation you can send messages to agents to do the non-idempotent parts. Messages sent to agents are dispatched only when the transaction finishes and are guaranteed to only be sent once.

鲜肉鲜肉永远不皱 2024-11-03 02:56:24

Clojure中的一点是,当你处理事务时,没有副作用,因为它们是一致的,并且当函数在更新共享值期间发现冲突时,函数将重新运行(我更喜欢重试),否则它将重新运行。成功提交更改。
如果必须重试,它将读取更新的值,因此没有副作用,您可能发现的问题是活锁,但它是由 Clojure 的重试次数限制来控制的。

The point in Clojure is that there is no side effect when you deal with Transactions, because they acre consistent, and the function will re-run (I prefer retry) when it finds a conflict during the update of the Shared Value, otherwise it will commit succesfuly the change.
If it has to retry, it will read the updated value, so there is no side effect, the problem you could find is a Livelock, but it is kind of controlled by a limit number in retries from Clojure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文