Looking through the api on record locking I''m confused. given the stateless nature of html, it''s entirely possible that someone might click on ''edit'' and then simply abandon their ''edit'' functions without ever saving - which tells me that I should just have a column in each table called ''lock_version'' with a default of 0 - (Opportunistic locking) right? Then I need a method in each model employing record locking to rescue any exceptions raised by multiple people trying to edit without saving and in essence checking out the data again and discarding their edits. Do I have this right? Craig --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
On Apr 21, 2008, at 10:43 AM, Craig White wrote:> > Looking through the api on record locking I''m confused. > > given the stateless nature of html, it''s entirely possible that > someone > might click on ''edit'' and then simply abandon their ''edit'' functions > without ever saving - which tells me that I should just have a > column in > each table called ''lock_version'' with a default of 0 - (Opportunistic > locking) right? > > Then I need a method in each model employing record locking to rescue > any exceptions raised by multiple people trying to edit without saving > and in essence checking out the data again and discarding their edits. > > Do I have this right? > > CraigYes, you are right. It is dangerous to leave a record locked any longer than necessary, and very dangerous to leave it locked if you don''t absolutely know the transaction will complete. If you want optimistic locking, add a column called lock_version. If you want pessimistic locking, see this: http://ryandaigle.com/articles/2006/6/27/whats-new-in-edge-rails-pessimistic-locking It''s safe to use optimistic locking across http requests if you don''t mind failed updates when collisions occur. Otherwise, consider pessimistic, as described. G''luck! --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
On Mon, 2008-04-21 at 11:08 -0700, s.ross wrote:> On Apr 21, 2008, at 10:43 AM, Craig White wrote: > > > > > Looking through the api on record locking I''m confused. > > > > given the stateless nature of html, it''s entirely possible that > > someone > > might click on ''edit'' and then simply abandon their ''edit'' functions > > without ever saving - which tells me that I should just have a > > column in > > each table called ''lock_version'' with a default of 0 - (Opportunistic > > locking) right? > > > > Then I need a method in each model employing record locking to rescue > > any exceptions raised by multiple people trying to edit without saving > > and in essence checking out the data again and discarding their edits. > > > > Do I have this right? > > > > Craig > > Yes, you are right. It is dangerous to leave a record locked any > longer than necessary, and very dangerous to leave it locked if you > don''t absolutely know the transaction will complete. If you want > optimistic locking, add a column called lock_version. If you want > pessimistic locking, see this: > > http://ryandaigle.com/articles/2006/6/27/whats-new-in-edge-rails-pessimistic-locking > > It''s safe to use optimistic locking across http requests if you don''t > mind failed updates when collisions occur. Otherwise, consider > pessimistic, as described.---- I''m surprised that this gets so little discussion. Clearly pessimistic locking is not where I want to go (too many untrained users). This rescue must be built into each model''s ''update'' function I gather...I think I get it. Thanks Craig --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
On Mon, 2008-04-21 at 10:43 -0700, Craig White wrote:> Looking through the api on record locking I''m confused. > > given the stateless nature of html, it''s entirely possible that someone > might click on ''edit'' and then simply abandon their ''edit'' functions > without ever saving - which tells me that I should just have a column in > each table called ''lock_version'' with a default of 0 - (Opportunistic > locking) right? > > Then I need a method in each model employing record locking to rescue > any exceptions raised by multiple people trying to edit without saving > and in essence checking out the data again and discarding their edits.---- OK - something must be wrong with my controller code then. I added ''lock_version'' to my ''clients'' table and restarted my mongrels. in script/console, opportunistic locking works as advertised in the API but using 2 separate browsers (1 Firefox, 1 Konqueror) with 2 separate sessions, I can update either in any order without an issue and the updates are saved and the ''lock_version'' value simply increments. this is my controller code...can you see how I might be defeating opportunistic locking? id = params[:id] if id && @client.valid? begin @client.update_attributes(params[:client]) flash[:notice] = ''Client was successfully updated.'' redirect_to :back rescue flash[:notice] = "Client record was changed by someone else \ while you were editing and you will have to edit again, \ starting over" redirect_to :back end else flash[:notice] = "Danger Will Robinson" redirect_to :back end Thanks Craig --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
On Mon, 2008-04-21 at 15:42 -0700, Craig White wrote:> > On Mon, 2008-04-21 at 10:43 -0700, Craig White wrote: > > Looking through the api on record locking I''m confused. > > > > given the stateless nature of html, it''s entirely possible that someone > > might click on ''edit'' and then simply abandon their ''edit'' functions > > without ever saving - which tells me that I should just have a column in > > each table called ''lock_version'' with a default of 0 - (Opportunistic > > locking) right? > > > > Then I need a method in each model employing record locking to rescue > > any exceptions raised by multiple people trying to edit without saving > > and in essence checking out the data again and discarding their edits. > ---- > OK - something must be wrong with my controller code then. > > I added ''lock_version'' to my ''clients'' table and restarted my mongrels. > > in script/console, opportunistic locking works as advertised in the API > > but using 2 separate browsers (1 Firefox, 1 Konqueror) with 2 separate > sessions, I can update either in any order without an issue and the > updates are saved and the ''lock_version'' value simply increments. > > this is my controller code...can you see how I might be defeating > opportunistic locking? > > id = params[:id] > if id && @client.valid? > begin > @client.update_attributes(params[:client]) > flash[:notice] = ''Client was successfully updated.'' > redirect_to :back > rescue > flash[:notice] = "Client record was changed by someone else \ > while you were editing and you will have to edit again, \ > starting over" > redirect_to :back > end > else > flash[:notice] = "Danger Will Robinson" > redirect_to :back > end---- never mind...I see why this is happening...first step in my ''update'' method retrieves the current value of ''lock_version'' from the record. I had to submit the value of lock_version in the params hash as a hidden_field. Duh... Craig --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
On 21 Apr 2008, at 23:42, Craig White wrote:> > OK - something must be wrong with my controller code then. > > I added ''lock_version'' to my ''clients'' table and restarted my > mongrels. > > in script/console, opportunistic locking works as advertised in the > API > > but using 2 separate browsers (1 Firefox, 1 Konqueror) with 2 separate > sessions, I can update either in any order without an issue and the > updates are saved and the ''lock_version'' value simply increments. >This is intended. Opportunistic locking guards you from changes happening behind your back in between you doing foo = Foo.find(123) and foo.save Pessimistic locking has a similar sort of the database transaction it''s enclosed in, and you wouldn''t want that lasting beyond a single request (apart from anything else, if you have more than 1 mongrel, there''s no guarantee you won''t get some requests served by 1 mongrel and one by the other). It sounds as though you''re worried about the record changing in between the user viewing the form and you saving the record. There''s no support for that builtin, but I think you could extend the principle of optimistic locking (include the current lock_version as a hidden field on the form) Fred> this is my controller code...can you see how I might be defeating > opportunistic locking? > > id = params[:id] > if id && @client.valid? > begin > @client.update_attributes(params[:client]) > flash[:notice] = ''Client was successfully updated.'' > redirect_to :back > rescue > flash[:notice] = "Client record was changed by someone else \ > while you were editing and you will have to edit again, \ > starting over" > redirect_to :back > end > else > flash[:notice] = "Danger Will Robinson" > redirect_to :back > end > > Thanks > > Craig > > > >--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
On Tue, 2008-04-22 at 00:11 +0100, Frederick Cheung wrote:> It sounds as though you''re worried about the record changing in > between the user viewing the form and you saving the record. There''s > no support for that builtin, but I think you could extend the > principle of optimistic locking (include the current lock_version as a > hidden field on the form) >---- yeah - I sort of figured that out (the hidden field on the form sending back the lock_version value that it checked out) but this causes me a problem with validations now. Here''s the issue in simplistic form... controller code... before optimistic locking if @client.update_attributes(params[:client]) flash[:notice] = "Bravo" redirect_to :back else flash[:notice] = @client.validate redirect_to :back end NOW, with opportunistic locking... if whatever begin @client.update_attributes(params[:client]) flash[:notice] = "Bravo" redirect_to :back rescue flash[:notice] = "Something changed in the interim" redirect_to :back end end The validate is lost in the rescue...how do I get my cake too? Thanks Craig --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
On Mon, 2008-04-21 at 16:35 -0700, Craig White wrote:> On Tue, 2008-04-22 at 00:11 +0100, Frederick Cheung wrote: > > > It sounds as though you''re worried about the record changing in > > between the user viewing the form and you saving the record. There''s > > no support for that builtin, but I think you could extend the > > principle of optimistic locking (include the current lock_version as a > > hidden field on the form) > > > ---- > yeah - I sort of figured that out (the hidden field on the form sending > back the lock_version value that it checked out) but this causes me a > problem with validations now. > > Here''s the issue in simplistic form... > > controller code... > > before optimistic locking > > if @client.update_attributes(params[:client]) > flash[:notice] = "Bravo" > redirect_to :back > else > flash[:notice] = @client.validate > redirect_to :back > end > > NOW, with opportunistic locking... > > if whatever > begin > @client.update_attributes(params[:client]) > flash[:notice] = "Bravo" > redirect_to :back > rescue > flash[:notice] = "Something changed in the interim" > redirect_to :back > end > end > > The validate is lost in the rescue...how do I get my cake too?---- I guess the question I am asking is if I have @client and params[:client] how do I validate @client with params[:client] modifications prior to saving it? Craig --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Craig - On 21-Apr-08, at 7:50 PM, Craig White wrote:> > > On Mon, 2008-04-21 at 16:35 -0700, Craig White wrote: >> On Tue, 2008-04-22 at 00:11 +0100, Frederick Cheung wrote: >> >>> It sounds as though you''re worried about the record changing in >>> between the user viewing the form and you saving the record. There''s >>> no support for that builtin, but I think you could extend the >>> principle of optimistic locking (include the current lock_version >>> as a >>> hidden field on the form) >>> >> ---- >> yeah - I sort of figured that out (the hidden field on the form >> sending >> back the lock_version value that it checked out) but this causes me a >> problem with validations now. >> >> Here''s the issue in simplistic form... >> >> controller code... >> >> before optimistic locking >> >> if @client.update_attributes(params[:client]) >> flash[:notice] = "Bravo" >> redirect_to :back >> else >> flash[:notice] = @client.validate >> redirect_to :back >> end >> >> NOW, with opportunistic locking... >> >> if whatever >> begin >> @client.update_attributes(params[:client]) >> flash[:notice] = "Bravo" >> redirect_to :back >> rescue >> flash[:notice] = "Something changed in the interim" >> redirect_to :back >> end >> end >> >> The validate is lost in the rescue...how do I get my cake too? > ---- > I guess the question I am asking is if I have > > @client > and params[:client] > > how do I validate @client with params[:client] modifications prior to > saving it? > > Craig@client.attributes = params[:client] @client.valid? cheers, Jodi --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
On Mon, 2008-04-21 at 19:53 -0400, Jodi Showers wrote:> Craig - > > On 21-Apr-08, at 7:50 PM, Craig White wrote: > > > > > > > On Mon, 2008-04-21 at 16:35 -0700, Craig White wrote: > >> On Tue, 2008-04-22 at 00:11 +0100, Frederick Cheung wrote: > >> > >>> It sounds as though you''re worried about the record changing in > >>> between the user viewing the form and you saving the record. There''s > >>> no support for that builtin, but I think you could extend the > >>> principle of optimistic locking (include the current lock_version > >>> as a > >>> hidden field on the form) > >>> > >> ---- > >> yeah - I sort of figured that out (the hidden field on the form > >> sending > >> back the lock_version value that it checked out) but this causes me a > >> problem with validations now. > >> > >> Here''s the issue in simplistic form... > >> > >> controller code... > >> > >> before optimistic locking > >> > >> if @client.update_attributes(params[:client]) > >> flash[:notice] = "Bravo" > >> redirect_to :back > >> else > >> flash[:notice] = @client.validate > >> redirect_to :back > >> end > >> > >> NOW, with opportunistic locking... > >> > >> if whatever > >> begin > >> @client.update_attributes(params[:client]) > >> flash[:notice] = "Bravo" > >> redirect_to :back > >> rescue > >> flash[:notice] = "Something changed in the interim" > >> redirect_to :back > >> end > >> end > >> > >> The validate is lost in the rescue...how do I get my cake too? > > ---- > > I guess the question I am asking is if I have > > > > @client > > and params[:client] > > > > how do I validate @client with params[:client] modifications prior to > > saving it? > > > > Craig > > > @client.attributes = params[:client] > @client.valid?---- shameful of me to be working with Rails for 2 years now and I never knew... @client.attributes = params[:client] was possible Thanks Craig --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Jodi Showers wrote:> > @client.attributes = params[:client] > @client.valid? > >isn''t @client.update_attributes params[:client] a shortcut for the example above ? Lionel --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
On 22 Apr 2008, at 09:45, Lionel Bouton wrote:> > Jodi Showers wrote: >> >> @client.attributes = params[:client] >> @client.valid? >> > > isn''t > > @client.update_attributes params[:client] > > a shortcut for the example above ?No, since update_attributes actually performs the save, whereas valid? will just run the validations. Fred --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Frederick Cheung wrote:> [...] > No, since update_attributes actually performs the save, whereas valid? > will just run the validations. > >Whoops. I had a feeling my question was stupid. Still need coffee... --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
On Tue, 2008-04-22 at 12:01 +0100, Frederick Cheung wrote:> > On 22 Apr 2008, at 09:45, Lionel Bouton wrote: > > > > Jodi Showers wrote: > >> > >> @client.attributes = params[:client] > >> @client.valid? > >> > > > > isn''t > > > > @client.update_attributes params[:client] > > > > a shortcut for the example above ? > No, since update_attributes actually performs the save, whereas valid? > will just run the validations.---- which of course is a problem once you introduce begin/rescue code into a ''save'' function because the validation results get swallowed by the rescue. I have one particular controller that does a bunch of hoops and I started by doing this... if params[:placement][:lock_version].to_i != @placement.lock_version flash[:notice] = "Placement record was changed by someone else" redirect_to :back return false end which as far as I can tell, still leaves a tiny sliver of time for someone to actually update this same record before the ''save'' code is executed but in this model, I''m willing to take the risk because there are so few people who have write access to this model and the likelihood of two people editing the same record at the same time is really, really small. (yeah I know...transactions) I''m glad I finally took a look at record locking but it does complicate things. Thanks all Craig --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---