Я не думаю, что вы должны думать о компромиссах между atoms
против refs
, так как они используются для разных ситуаций.
Вы должны использовать atom
, если хотите что-то изменить atomically.
refs
использовать STM и включать в себя различные вещи, которые изменяются одновременно, в транзакции.
В вашей конкретной ситуации вы должны отвечать на вопрос о том, что вы меняете.
- Это одна вещи, которую вы хотите/может изменить в одном шаге
- Существуют различные вещи, которые вы хотите/потребность изменить транзакционно
При переключении старой базы данных для новых базу данных и изменить все вместе, чтобы изменить одно поле, и поэтому вы говорите, что ваша база данных - atom
, вы злоупотребляете механизмом.
Надеюсь, что это различие помогает, для вашего примера я бы использовал атом, тем не менее.
Существует good summary here с мотивами, стоящими за каждой стратегией.
+1 для сбалансированного ответа, но это немного смутило меня; 'Кроме того, STM взаимодействует с агентами - действия, отправленные агентам из транзакции, будут выполняться тогда и только тогда, когда транзакция совершает транзакции.' - Не будут ли выполняться действия при замене атома? Это означает, что действия будут выполняться независимо от успеха. – muhuk
Если вы «отправляете» из функции, переданной 'swap!', То да, 'send' будет переустанавливаться при каждой попытке. Попробуйте, например. '(def a (atom 0)) (def ag (агент nil)) (do (future (swap! a (fn [x] (Thread/sleep 5000) (send ag println: foo) (inc x)))) (Thread/sleep 1000) (swap! A inc)) ': здесь': foo' будет печататься дважды; если вы использовали Ref вместо Atom, он будет печататься только один раз. –
Вы правы. Спасибо за пример! – muhuk