gaveeno
2009-Mar-08 10:32 UTC
model.reload not working; preventing me from rescuing optimistic lock exception
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 with optimistic locking is 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 way optimistic 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
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
gaveeno
2009-Mar-08 10:39 UTC
Re: model.reload not working; preventing me from rescuing optimistic lock exception
Here''s the code again, just formatted slightly better
### 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.
## 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
<gavin.to...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
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 with optimistic locking is 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 way optimistic 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
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
Frederick Cheung
2009-Mar-08 12:58 UTC
Re: model.reload not working; preventing me from rescuing optimistic lock exception
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 <gavin.to...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 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 with optimistic locking is 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 way optimistic >> 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 rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
gaveeno
2009-Mar-08 19:19 UTC
Re: model.reload not working; preventing me from rescuing optimistic lock exception
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
<frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
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
<gavin.to...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 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
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---