如何使clojure STM程序持久化?
我正在编写一个使用STM的clojure程序。目前,我正在从数据库启动时填充STM(使用REF),然后在dosync事务成功时异步更新数据库。我不知道我是否用正确的方法来做这件事,或者是否有更好的标准技术来做这件事。有谁能向我解释一下他们是如何在Clojure程序中将STM的ACI属性转换成ACID的吗?STM模型非常适合跟踪系统变化时的多址访问。它不太直接适用于数据持久性,在这种情况下,更改需要在访问它们的线程的生命周期之外才可访问如何使clojure STM程序持久化?,clojure,stm,Clojure,Stm,我正在编写一个使用STM的clojure程序。目前,我正在从数据库启动时填充STM(使用REF),然后在dosync事务成功时异步更新数据库。我不知道我是否用正确的方法来做这件事,或者是否有更好的标准技术来做这件事。有谁能向我解释一下他们是如何在Clojure程序中将STM的ACI属性转换成ACID的吗?STM模型非常适合跟踪系统变化时的多址访问。它不太直接适用于数据持久性,在这种情况下,更改需要在访问它们的线程的生命周期之外才可访问 通常,最好将ACID中的“D”与STM分开考虑。一般来说,将
通常,最好将ACID中的“D”与STM分开考虑。一般来说,将ACID中的“D”添加到任何程序中都不是小事,这取决于程序的要求。在确定实现之前,需要确定一个重要的规范 是否对数据库进行多线程/多进程访问? 从问题主体来看,您的程序似乎仅在启动时读取,在STM发生更改后写入,此时数据库会将STM中的值延迟一小段时间。但是,如果其他程序(包括程序的其他实例)访问数据库,则需要使用锁,在事务之前锁定对数据库的访问,在写入数据库之后解锁(作为补充,请注意,在您的情况下,数据库可以是任何东西,包括文件系统中的一个简单文件)。当您有多个读写操作时,没有办法解决这个问题,因为它们都是涉及数据库的副作用 如果没有多个访问,那么异步写入就可以了,因为在进行访问时,程序是单线程的,因此保证代码始终按顺序工作 如果您只有多个写入线程,并且启动后只有一个实例没有读取,那么您只需要确保正确的写入顺序。您可以使用代理执行此操作,其中代理基本上是对数据库的写入操作队列。您可以将dosync包绕在引用事务和代理周围,从而持久性和持久性 一般来说,涉及副作用的需求越复杂,您就必须采取越多的技巧来确保ACID。如果您有额外的需求,那么我给出的实现可能需要更改 编辑:
(def db-agent (agent dummy-value))
(defn db-write [_ data] ;; make this intelligent to handle when db is not up
(try
(write-to-db data)
(catch ... database fails, do a retry or let user know of problem))
_)
;; in the transaction code
(dosync
(alter my-ref ...)
(send-off db-agent db-write @my-ref)) ;; ensure db gets written to
如果您想要一个具有快速内存访问能力的数据库,并且可以不时地在后台持久化,那么请使用真正的数据存储,而不是尝试构建自己的数据库,这将是一项相当大的工作
和是两个不错的选择,但还有很多其他选择。您可以分别在Redis和Mongo的和中找到Clojure库。您可能会感兴趣:
其他方法对程序员来说可能不那么透明。啊,最后有人试图回答实际问题,谢谢:)没有对数据库的多进程访问(H2或Oracle)。访问数据库的唯一进程是Clojure程序本身。您的程序是多线程读取还是多线程写入?如果是多线程读取,是在启动后进行的吗?启动后,是从持久存储中读取多线程,还是从内存引用中读取多线程?好的,那么我建议使用代理就足够了,我将编辑帖子以反映一些代码。谢谢,这是使用代理保存的有用方法,确保文章是连续的,我想?FleetDB链接到一个关于葡萄酒的博客。