结合使用 STM 和数据库事务
我一直在使用 Haskell 的 STM 库,我真的很喜欢编写事务的能力以及 STM 的一般“你不会出错”的性质。
出于充分的理由,STM 不允许事务内进行 IO 操作。无法重试 IO 操作。 (在此插入发射导弹参考)。另一方面,数据库事务确实有一些非常相似的原子性保证。有没有公认的方法将两者一起使用?
I have been using Haskell's STM library and I really like the ability to compose transactions and the general "you-can't-get-this-wrong" nature of STM.
For good reason, STM does not allow IO actions within a transaction. There is no way to retry an IO action. (insert Launch missiles reference here). Database transactions on the other hand do have some atomicity guarantees that are very similar. Is there an accepted way to use the two together?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
将不同类型的事务交错到单个事务概念中称为“事务增强”,目前在 Haskell 的 STM 中还没有很好的方法来做到这一点。但是,有一种方法可以构建仅在提交或仅在重试时执行的操作:http:// hackage.haskell.org/package/stm-io-hooks
此外,您可以尝试 twilight-stm 项目,它在事务结束和实际提交之间提供了明确的“暮光”。据我所知,所提供的代码更多的是一种参考实现,而不是针对性能进行调整的代码,但是:http: //proglang.informatik.uni-freiburg.de/projects/twilight/
尽管如此,根据您的应用程序,它可能会很快满足您的目的。
Interleaving different sorts of transactions into a single transaction notion is called "transactional boosting" and there isn't a great way to do it in Haskell's STM at the moment. There is, however, a way to build up actions to be performed only on commit or only on retry: http://hackage.haskell.org/package/stm-io-hooks
Additionally, you could try the twilight-stm project, which provides an an explicit "twilight" between transactions ending and actual commit. As far as I know, the code provided is more of a reference implementation than one tuned for performance, however: http://proglang.informatik.uni-freiburg.de/projects/twilight/
Nonetheless, depending on your application, it may turn out to be plenty-fast for your purposes.
来自不太熟悉数据库的人的一些一般帮助:
从技术上讲,您可以使用
unsafeIOToSTM
,因此,如果通过修改数据库的 IO 操作保证原子性,那么应该没问题。只需编写一个使用unsafeIOToSTM
的桥接器,然后在代码中使用该桥接器即可避免在代码中添加不安全的内容。您还可以使用 STM (IO a),但这并不总是适合您的目的,例如
或
返回要从 STM 执行的数据库查询的位置。这是安全的,但与您对 mVar 所做的事情相比受到更多限制,因此无法在您返回的 IO 操作中进行修改(这对于安全性来说是一件好事,因为它保持了原子性)
Some general help from someone who hasn't dealt with Databases much:
You can technically use
unsafeIOToSTM
, so if you are guaranteed atomicity by the IO action which modifies the database, it should be fine. Just write a bridge that usesunsafeIOToSTM
and then use that bridge in your code to avoid litering your code with unsafe things.You can also use an STM (IO a) but this doesn't always suit your purpose, like
or
Where you return the database query to perform from STM. This is safe but much more limited as what you do with mVar's and such cannot be modified from within the IO action you return (which is a good thing with regard to safety as it keeps the atomicity)