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 -~----------~----~----~----~------~----~------~--~---