ensure validates that a ref’s value remains unchanged during the current transaction. It is used inside dosync when a transaction must observe a ref without allowing that value to change concurrently. section 14.4
Guarding a transaction with ensure
(def votes {"honeypot" (ref 0) "candidate-0" (ref 0) "candidate-1" (ref 0)}) (defn batch [prefs] (future (dosync (ensure (votes "honeypot")) (doseq [color prefs :while (< @(votes "honeypot") 5)] (update votes color commute inc))))) Running two batches produces a result such as: {:total-votes 115, :winner "candidate-1", :fraud? true} Here, ensure checks the honeypot ref while the transaction processes vote preferences. section 14.4
The practical shape of ensure is:
- Pass it the ref whose value must remain unchanged during the transaction. section 14.4
- Place it within dosync alongside coordinated ref operations such as commute. section 14.4
