I'm new to Clojure and have been trying to understand its transaction model.
When playing with alter
and commute
, I noticed that if I alter
a ref after commute
it, then the transaction will not commit anything (or makes no change to anything).
For example:
(def counter (ref 0))
(def i (ref 0))
(future (dosync
(ref-set counter 1)
(ref-set i 1)
(commute counter inc)
(alter counter inc)))
Both @counter
and @i
will be 0, but if I swap commute
and alter
or use two commute
s or two alter
s in this case it will produce the desired result (3 and 1, respectively).
I've read some posts explaining that the behavior of commute
and alter
is a bit different in that commute
is actually executed twice in a transaction (one where it stands, the other at the "commit" stage) and ignores inconsistent snapshots of the ref. I'm just confused by the strange behavior of the combination of these two.
Could anyone help explain how it works? Thanks in advance!