Assuming that the ref in the following code is modified in other transactions as well as the one below, my concern is that this transaction will run until it's time to commit, fail on commit, then re-run the transaction.
(defn modify-ref [my-ref]
(dosync (if (some-prop-of-ref-true @my-ref)
(alter my-ref long-running-calculation))))
Here's my fear in full:
- modify-ref is called, a transaction is started (call it A), and long-running-calculation starts
- another transaction (call it B) starts, modifies my-ref, and returns (commits successfully)
- long-running-calculation continues until it is finished
- transaction A tries to commit but fails because my-ref has been modified
- the transaction is restarted (call it A') with the new value of my-ref and exits because some-prop is not true
Here's what I would like to happen, and perhaps this is what happens (I just don't know, so I'm asking the question :-)
When the transaction B commits my-ref, I'd like transaction A to immediately stop (because the value of my-ref has changed) and restart with the new value. Is that what happens?
The reason I want this behavior is so that long-running-calculation doesn't waste all that CPU time on a calculation that is now obsolete.
I thought about using ensure
, but I'm not sure how to use it in this context or if it is necessary.