Подтвердить что ты не робот

Как я могу сделать программу STM clojure постоянной?

Я пишу программу clojure, которая использует STM. В настоящий момент я заполняю STM (используя refs) при запуске из базы данных, а затем асинхронно обновляю базу данных всякий раз, когда транзакция dosync завершается успешно. Я понятия не имею, правильно ли я делаю это правильно, или если для этого есть более стандартная техника. Может ли кто-нибудь объяснить мне, как они делают ACI-свойства STM в ACID в своих программах clojure?

4b9b3361

Ответ 1

В общем, добавление "D" в ACID в любую программу не является тривиальным и зависит от требований программы. Существует одна важная спецификация, которая должна быть определена до того, как можно будет определить реализацию.

Существует ли многопоточный/многопроцессный доступ к базе данных?

Из тела вопроса ваша программа, по-видимому, читает только при запуске и записывает после изменения STM, где база данных будет задерживать значения в STM на небольшое количество времени. Однако , если к базе данных обращаются другие программы, включая другие экземпляры вашей программы, тогда вам нужно будет использовать блокировки, где вы блокируете доступ к базе данных прямо перед транзакциями и разблокируете после записи в базы данных (в качестве примечания, обратите внимание, что база данных в вашем случае может быть любой, включая простой файл в файловой системе). Нет никакого способа обойти это, если у вас есть несколько операций чтения и записи, потому что они оба являются побочными эффектами, которые связаны с базой данных.

Если не существует множественного доступа, то асинхронная запись прекрасна, потому что гарантируется, что код всегда будет работать в порядке, так как ваша программа будет однопоточной, когда приходит доступ.

Если у вас есть только несколько потоков записи и без чтения после запуска только с одним экземпляром, вам нужно только обеспечить правильный порядок записи. Вы можете сделать это с помощью агентов, где агент в основном представляет собой очередь операций записи в базу данных. Вы переносите dosync вокруг ссылочных транзакций и агента, давая вам прочность в дополнение к постоянству.

В целом, чем сложнее требования, связанные с побочными эффектами, тем больше уловок вам нужно будет сделать для обеспечения ACID. Если у вас есть дополнительные требования, то реализация, которую я дал, может измениться.

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

Ответ 2

Вам может быть интересно:

Другие подходы могут быть не столь прозрачными для программиста.

Ответ 3

Модель STM очень хорошо подходит для отслеживания множественного доступа к системам по мере их изменения. Он менее точно подходит для сохранения данных, когда изменения должны быть доступны за пределы жизни потоков, которые обращаются к ним.

Как правило, хорошо думать о "D" в ACID отдельно от STM

Ответ 4

Если вам нужна база данных с быстрым доступом в памяти и время от времени сохраняется за кулисами, тогда используйте реальное хранилище данных, а не пытайтесь создать свой собственный, что будет довольно большой работой.

Redis и MongoDB - два хорошие варианты, но есть и многие другие. Библиотеки Clojure можно найти в https://github.com/ragnard/redis-clojure и https://github.com/somnium/congomongo для Redis и Mongo соответственно.