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

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


person yazz.com    schedule 23.12.2010    source источник


Ответы (4)


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

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

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

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

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

В общем, чем сложнее требования, связанные с побочными эффектами, тем больше трюков вам придется делать, чтобы обеспечить 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
person bmillare    schedule 29.12.2010
comment
Ах, наконец-то кто-то пытается ответить на актуальный вопрос, спасибо :) Нет мультипроцессного доступа к базе данных (H2 или Oracle). Единственный процесс, который обращается к базе данных, — это сама программа Clojure. - person yazz.com; 30.12.2010
comment
Есть ли в вашей программе многопоточное чтение или многопоточная запись? Если многопоточное чтение, это когда-либо после запуска? - person bmillare; 30.12.2010
comment
После запуска выполняется многопоточное чтение из постоянного хранилища или из ссылки в памяти? - person bmillare; 30.12.2010
comment
Хорошо, тогда моего предложенного использования агентов должно быть достаточно, я отредактирую сообщение, чтобы отразить некоторый код. - person bmillare; 31.12.2010
comment
спасибо, полезный способ сохранения с помощью агентов, я думаю, убедитесь, что записи являются последовательными? - person yazz.com; 31.12.2010
comment
Да, чтобы сохранить порядок записи, также известный как сериализация. - person bmillare; 31.12.2010

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

  1. Модифицированное ядро ​​Clojure Алиссы Кван, добавляющее постоянство ссылкам, см.: ANN: Надежные ссылки с гарантиями ACID – этап I, ANN: Durable Clojure — этап II — постоянные структуры данных, ANN: Durable Clojure — функции и замыкания

  2. Библиотека Сергея Диденко, которая не дает сильной гарантии долговечности, но весьма близка к ней: Simple- Постоянство для Clojure

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

person Sergey    schedule 30.12.2010
comment
Ссылка FleetDB ведет на блог о вине. - person Petrus Theron; 10.07.2015

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

Обычно хорошо думать о 'D' в ACID отдельно от STM.

person Arthur Ulfeldt    schedule 24.12.2010

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

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

person trptcolin    schedule 29.12.2010