I've been thinking about this more. Suppose I do something like this.

(def my-ref (ref 1))

(defn f1 []
  (dosync
    (ref-set my-ref 10)))

(defn f2 []
  (dosync
    (ref-set my-ref 5)
    (commute my-ref #(inc %))))

(let [t1 (Thread. f1)
      t2 (Thread. f2)]
  (.start t1)
  (.start t2)
  (.join t1)
  (.join t2))

(println "my-ref =" @my-ref)

Is there any way that my-ref will have a value of 11 at the end?
That's what would happen if the transaction in f1 committed while the
transaction in f2 was running because according to the commute doc
string, it would use the latest committed value. What I see in
LockingTransaction.java though tells me that because the transaction
in f2 does a ref-set before calling commute, when the commute function
runs a second time during the commit, it will use the in-transaction
value of 5 instead and result in a value of 6 for my-ref instead of
11.

On Aug 2, 2:20 pm, Mark Volkmann <r.mark.volkm...@gmail.com> wrote:
> The doc for commute says "At the commit point of the transaction, sets
> the value of ref to be:
> (apply fun most-recently-committed-value-of-ref args)".
>
> Looking at the source code in LockingTransaction.java, that doesn't
> seem to always be the case. I see this:
> f.fn.applyTo(RT.cons(vals.get(ref), f.args))
>
> vals is a HashMap of in-transaction values, not most recently committed 
> values.
>
> Inside a transaction, Refs get in-transaction values if you do a
> ref-set or alter on them.
> Within a transaction you can ref-set or alter a Ref and then do a
> commute on the same Ref.
> You can't reverse the order. Once you do a commute on a Ref, you can't
> do a ref-set or alter on it in the same transaction.
>
> During transaction commit and immediately before the commute functions
> for the Ref are called, it determines whether the Ref has an
> in-transaction value, meaning that ref-set or alter was called on it.
> If it does not then the most recently committed value for the Ref is
> used for the in-transaction value.
>
> So I think it is only partially true to say that when commute
> functions are rerun during a commit, they use the most recently
> committed values of Refs. That only happens if ref-set and alter were
> not used on the Ref before the call to commute.
>
> Am I understanding this correctly?
>
> --
> R. Mark Volkmann
> Object Computing, Inc.
--~--~---------~--~----~------------~-------~--~----~
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