Congratulations, you've found a bug in clojure 1.3 beta2, see:

 look with my clojure 1.2.0 version :

;; Clojure 1.2.0
=> (def thread (agent "Thread"))
   (def account (ref 1000))
   (send thread
         (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000) agt))
         account)
   (time (dosync (ref-set account 2000)))
#'user/thread
#'user/account
#<Agent@7e543cb1: "Thread">
"Elapsed time: 0.498106 msecs"
2000
=> ;; 10 seconds later :
=> @account
2100


And now with clojure 1.3 beta1 :

;; Clojure 1.3.0-beta1
=> (def thread (agent "Thread"))
   (def account (ref 1000))
   (send thread
         (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000) agt))
         account)
   (time (dosync (ref-set account 2000)))
   ;; 10 seconds later :
#'user/thread
#'user/account
#<Agent@6bf51e5c: "Thread">
"Elapsed time: 0.270225 msecs"
2000
=> @account
2100

And now with Clojure 1.3-beta2
;; Clojure 1.3.0-beta2
=> (def thread (agent "Thread"))
   (def account (ref 1000))
   (send thread
         (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000) agt))
         account)
   (time (dosync (ref-set account 2000)))
#'user/thread
#'user/account
#<Agent@50fba502: "Thread">
"Elapsed time: 7957.328798 msecs"
2000
   ;; 10 seconds later :
=> @account
2000
   ;; 10 more seconds later :
=> @account
2000

2011/8/30 Laurent PETIT <laurent.pe...@gmail.com>

> 2011/8/29 Dominikus <dominikus.herzb...@gmail.com>
>
>> Thanks a lot for this detailed analysis and the pointers to the Java
>> implementation, Stefan! That's excellent and very helpful.
>>
>> I still wonder, why the first transaction blocks write access. My
>> overall understanding of the transaction system is that changes to
>> referenced values remain in-transaction before committing them, a
>> write-lock shouldn't be needed. I'm surprised, that the second
>> transaction is the one who has to retry 71 times even though the first
>> transaction hasn't committed anything yet.
>>
>
> I must confess this behaviour also challenges my assumptions.
>
> Does this work the same whatever the clojure version used ?
>
>
>>
>> Cheers,
>>
>> Dominikus
>>
>> P.S.: Thanks for the idea to use 'future' to spawn a thread!
>>
>> On Aug 29, 5:42 pm, Stefan Kamphausen <ska2...@googlemail.com> wrote:
>> > 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 clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to