我想在不触发副作用的情况下对数据数据库进行操作。目标是在当前数据库的“替代”版本上工作,如果替代版本的创建成功,则提交数据。否则,数据库连接应保持其当前状态。
我发现datomic.api/with很好地解决了我的问题,但是我不知道什么是将在备用版本中创建的数据添加到数据连接的最佳方法。
下面是我当前的操作步骤:
(defn operation [conn]
(let [db (d/db conn)
current-t (d/basic-t db)
new-db (create-alternative-version db)]
(d/transact conn (d/datoms (d/since new-db current-t) :eavt))))目前,我得到以下错误:
ClassCastException datomic.db$datoms$reify__1559
cannot be cast to java.util.List datomic.api/transact你认为这种方法有意义吗?如果有更好的解决方案呢?
我还查看了sync api,但它似乎不适合用于此目的。
谢谢你的帮助
发布于 2017-01-14 19:52:18
事务处理程序上的with-db和db之间没有有效的同步。with-db是另一种选择,它不持有事务处理机连接上的任何锁或事务处理机上的当前数据库。
举个例子,假设您按d/with执行事务,并返回一个with-db,这是一个应用了事务的推测性数据库状态。然后检查结果数据库状态是否为“成功”(您还没有阐明成功是什么意思,但我假设它需要检查整个结果数据库状态的一部分)。不能保证相同的事务将导致实际数据库的相同状态,因为在这两个事务之间可能发生另一个事务。
此同步问题的典型解决方案是确定“成功”的最小检查,并在事务函数中实现该检查。在事务函数中,您可以在事务之前访问一致的数据库状态。事务函数在事务期间独立运行,如果事务不会导致数据库状态为“成功”,则可以使用这些函数让事务失败。让事务失败的另一种方法是在事务之前从数据库状态注入数据。如有必要,您可以在事务函数中使用d/with。
以下是事务函数的文档:http://docs.datomic.com/database-functions.html
您的示例不起作用,因为d/datom返回eavt元组,而事务将需要以:db/add、:db/retract或事务函数的ident开头的断言元组,或者映射用于更新。当然,您可以将eavt元组转换为这样的断言元组,但您可能会错过回溯(可以使用d/history、IDK)。将您应用于d/with的相同事务应用到d/transact会更容易一些。然而,如上所述,这不会为您提供任何同步保证。
https://stackoverflow.com/questions/41634722
复制相似问题