Я новичок в Clojure и пытаюсь понять ее модель транзакции. При игре с alter
и commute
я заметил, что если я alter
a ref после commute
, то сделка ничего не совершит (или ничего не меняет).Clojure: переключение до изменения в течение одной транзакции приводит к сбою транзакции
Например:
(def counter (ref 0))
(def i (ref 0))
(future (dosync
(ref-set counter 1)
(ref-set i 1)
(commute counter inc)
(alter counter inc)))
Оба @counter
и @i
будет 0, но если поменять местами commute
и alter
или использовать два commute
с или два alter
с в этом случае он будет производить желаемый результат (3 и 1, соответственно).
Я прочитал некоторые сообщения, объясняющие, что поведение commute
и alter
немного отличается тем, что commute
фактически выполняется дважды в транзакции (один, где она стоит, другой на стадии «фиксации») и игнорирует непоследовательным снимки реф. Меня просто смущает странное поведение комбинации этих двух.
Не могли бы помочь объяснить, как это работает? Заранее спасибо!
clojure 1.8: выводится в repl '{: status: failed,: val #error {: cause" Невозможно установить после коммутации ": через [{: type java.util.concurrent.ExecutionException ...' so не 'alter' после' commute'. Не удалось найти какой-либо конкретный документ для него - только [источник] (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LockingTransaction.java#L428) – birdspider