Как правило, добавление '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