خرید بک لینک

Vote count: 0

I'm wondering why the following 2 invocations behave differently depending on whether the ensure function is introduced inside or outside let:

=> "inside let"
(def account (ref 1000))
(def secured (ref false))
(def started (promise))
=> #'user/account
=> #'user/secured
=> #'user/started
(defn withdraw [account amount secured]
  (dosync
    (let [secured-value (ensure secured)]
      (deliver started true)
      (Thread/sleep 5000)
      (println :started)
      (when-not secured-value
        (alter account - amount))
      (println :finished))))
=> #'user/withdraw
(future (withdraw account 500 secured))
@started
(dosync (ref-set secured true))
=> #<core$future_call$reify__6320@7fbde8ed: :pending>
=> true
:started
:finished
=> true
@account
=> 500

========

    => "outside let"
(def account (ref 1000))
(def secured (ref false))
(def started (promise))
=> #'user/account
=> #'user/secured
=> #'user/started
(defn withdraw [account amount secured]
  (dosync
    (let [secured-value @secured]
      (deliver started true)
      (Thread/sleep 5000)
      (println :started)
      (when-not (ensure secured)
        (alter account - amount))
      (println :finished))))
=> #'user/withdraw
(future (withdraw account 500 secured))
@started
(dosync (ref-set secured true))
=> #<core$future_call$reify__6320@6adadff8: :pending>
=> true
=> true
:started
:started
:finished
@account
=> 1000

The expected semantics here is that when secured is set to true one shouldn't be able to withdraw any money.

My understanding is that ensure function will ensure that the secured ref has not changed during the time span of the transaction, so the second behavior with transaction restart seems reasonable, but why does it behave differently in the first case?

asked 1 min ago

برچسب: نویسنده: استخدام کار تاريخ: يکشنبه 2 خرداد 1395 ساعت: 5:32

صفحه بندی