我应该如何使Clojure STM程序持久? [英] How should I make a clojure STM program persistent?

查看:96
本文介绍了我应该如何使Clojure STM程序持久?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写一个使用STM的clojure程序。目前我在启动时从数据库填充STM(使用refs),然后每当dosync事务成功时异步更新数据库。我不知道我是否这样做正确的方式,或者如果有一个更好的标准技术这样做。有人可以向我解释他们如何在他们的Clojure程序中将STM的ACI属性设置为ACID?

I am writing a clojure program which uses the STM. At the moment I am populating the STM (using refs) at startup from a database, and then asynchronously updating the database whenever a dosync transaction succeeds. I have no idea if I am doing this the right way though, or if there is a better standard technique for doing this. Could anyone explain to me how they make the ACI properties of STM into ACID in their Clojure programs?

推荐答案

'AC'到任何程序的'D'不是微不足道的,取决于程序的要求。在确定实现之前需要确定一个重要的规范。

In general, adding the 'D' in ACID to any program is not trivial and depends on the program's requirements. There is one important specification that needs to be determined before the implementation can be determined.

有多线程/多进程访问数据库吗? / strong>

Is there multi-threaded/multi-process access to the database?

在问题正文中,您的程序似乎只在启动时读取,并在STM更改后写入,其中数据库将滞后STM通过少量的时间。但是,如果数据库被其他程序访问(包括程序的其他实例),则需要使用锁,在事务之前锁定对数据库的访问,并在写入数据库(注意,在你的情况下,数据库可以是任何东西,包括文件系统中的一个简单的文件)。当你有多个读和写时,没有办法,因为它们都是涉及数据库的副作用。

From the question body, your program appears to only read at startup and write after a change in the STM, where the database would lag the values in the STM by some small amount of time. However, if the database is accessed by other programs including other instances of your program, then you will need to use locks where you lock access to the database right before the transactions, and unlock after the write to the database (as a side note, note that the database in your case can be anything, including a simple file in the filesystem). There is no way around this when you have multiple read and writes, because they are both side effects that involve the database.

如果没有多个访问,那么异步写就好了,因为代码保证总是按顺序工作,因为你的程序在访问时是单线程的。

If there is not multiple access, then asynchronous writing is fine because the code is guaranteed to always work in order since your program is single threaded when in comes to access.

您只有多个写入线程,启动后只有一个实例,因此您只需要确保正确的写入顺序。您可以使用代理执行此操作,其中代理基本上是对数据库的写入操作的队列。

If you only have multiple write threads and no reads after startup with only a single instance, then you only need to ensure correct write order. You can do this with agents, where the agent is basically a queue of write operations to the database. You wrap the dosync around the reference transactions and the agent, giving you durability in addition to persistence.

一般来说,涉及副作用的要求越复杂,越多的技巧你将必须做到以确保ACID。如果您有其他要求,那么我提供的实现可能需要更改。

In general the more complicated the requirements that involve side effects, the more tricks you will have to do to ensure ACID. If you have additional requirements, then the implementations I gave might have to change.

EDIT:

(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

这篇关于我应该如何使Clojure STM程序持久?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆