Hey Fred,

Thanks for the input.  I didn't realize they all run in one
transaction, so that explains why my seemingly logical approach didn't
work.

I ended up using pessimistic locking:

  def update_credits(credits=1)
    return unless self.company
    credit_balance ||= CreditBalance.first(:conditions => "company_id
= #{self.company.id}",:lock => true)
    credit_balance.used_credits += credits
    credit_balance.save!
  rescue Exception
    credit_balance.reload(:lock => true)
    retry
  end

Since I'll always be using the update_credits to update a company's
credits used I can't foresee using pessimistic locking being a
problem.

Thanks again,
Gavin

On Mar 8, 5:58 am, Frederick Cheung <[email protected]>
wrote:
> On 8 Mar 2009, at 10:39, gaveeno wrote:
>
>
>
> >  rescue ActiveRecord::StaleObjectError
> >    credit_balance.reload
>
> >    ## i stopped the code here and
> >    ## saw that credit_balance didn't
> >    ## reflect the changes made in
> >    ## the console (see below) even though
> >    ## I checked via SQL and the
> >    ## database DID reflect the update.
>
> I'm not entirely sure if this is what you are asking, but the  
> before_*, save, after* sequence all runs in one transaction. You  
> should read up on transaction isolation levels (ie what changes from  
> other transactions a given transaction sees)
>
> Fred
>
> >    retry
> >  end
> > end
>
> > ## code executed in the console
> > ## after credit balance was loaded by
> > ## the update_credits method above.
> > ## 1 is the id of the company whose credit
> > ## balance I'm testing the code above with.
> > ## I updated used_credits with a random num.
>
> > c = CreditBalance.find(1)
> > c.update_attribute(:used_credits,999)
>
> > On Mar 8, 3:32 am, gaveeno <[email protected]> wrote:
> >> This error's driving me crazy...
>
> >> I'm trying to test the code that I wrote to rescue the
> >> ActiveRecord::StaleObjectError exception...this is the exception that
> >> can occur when a model withoptimisticlockingis updated by multiple
> >> processes concurrently.  For some reason, though, model.reload  
> >> doesn't
> >> seem to want to actually reload the model from the db when I rescue
> >> the exception.
>
> >> This is the code I'm using:
>
> >> ### Model
> >> class SmsTxn < ActiveRecord::Base
>
> >>   after_create :update_credits
>
> >>   def update_credits
>
> >>     return unless self.company
> >>     credit_balance ||= self.company.credit_balance
>
> >>     ## using ruby-debug, i stopped the code here and executed
> >>     ## the commands below (using script/console)
>
> >>     credit_balance.used_credits += 1
> >>     credit_balance.save
> >>     credit_balance.used_credits
>
> >>   rescue ActiveRecord::StaleObjectError
>
> >>     credit_balance.reload
>
> >>     ## i stopped the code here and saw that credit_balance didn't
> >> reflect the
> >>     ## changes made in the console (see below) even though I checked
> >> via SQL
> >>     ## and the database DID reflect the update.
>
> >>     retry
>
> >>   end
> >> end
>
> >> ### code executed in the console after credit balance was loaded by
> >> the update_credits method above
> >> c = CreditBalance.find(1)   # 1 is the id of the company whose credit
> >> balance
> >>                                        # I'm testing the code above
> >> with
>
> >> c.update_attribute(:used_credits,999) # I assigned a random number  
> >> for
> >> used_credits
>
> >> For some reason this is causing an infinite
> >> loop...credit_balance.reload is not reloading the model from what's  
> >> in
> >> the database so when it retries it gives the same error.  I first
> >> tried this test by updating the value directly via SQL, but that gave
> >> me the same problem so I thought that maybe the wayoptimistic 
> >>locking
> >> works it wasn't recognizing the change because it was outside of the
> >> Rails framework.
>
> >> Anybody know what I'm doing wrong??
>
> >> Thanks!
> >> Gavin
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to