The call to alter already wrote to the Ref, this requires a write-lock on
the ref (see LockingTransaction.java/doSet). After that it sleeps a while
and gets to its commit phase. The other transactions retries in the
meantime. Consider the following code, which introduces some atoms for
counting the retries
(defn tz []
(let [rr (ref 10)
a1 (atom 0)
a2 (atom 0)]
(println "Starting future")
(future
(dosync
(swap! a1 inc)
(alter rr + 100)
(Thread/sleep 8000)))
(println "Sleeping a bit")
(Thread/sleep 1000)
(println "Another dosync")
(time
(dosync
(swap! a2 inc)
(ref-set rr 1)))
[@rr @a1 @a2 (.getHistoryCount rr)]))
user> (tz)
Starting future
Sleeping a bit
Another dosync
"Elapsed time: 7001.554 msecs"
[1 1 71 0]
Note, how the 71 retries nice fit the approximately 7 seconds left and the
100 miliseconds time-out (LOCK_WAIT_MSECS) for the lock used in
LockingTransaction.java/tryWriteLock.
Transactions with significantly different run-times should be avoided,
although there is some point at which older transactions will get their
turn. This could be another explanation of the effect. Take a look at the
barge-function in LockingTransaction.java
Hope this helps,
Stefan
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en