#59
Jul 18, 2007

Optimistic Locking

When two people attempt to update the same record near the same time, one of the updates will likely be overwritten. You can solve this problem with optimistic locking.
Download (16.4 MB, 7:26)
alternative download for iPod & Apple TV (10.4 MB, 7:26)
# migrations/011_add_products_lock_version.rb
add_column :products, :lock_version, :integer, :default => 0, :null => false

# products_controller.rb
def update
  @product = Product.find(params[:id])
  if @product.update_attributes(params[:product])
    flash[:notice] = "Successfully updated product."
    redirect_to product_path(@product)
  else
    render :action => 'edit'
  end
rescue ActiveRecord::StaleObjectError
  @product.reload
  render :action => 'conflict'
end
<!-- _form.rhtml -->
<%= f.hidden_field :lock_version %>

<!-- conflict.rhtml -->
<% title "Edit Product Conflict" %>

Someone edited the product the same time you did. Please re-apply your changes to the product.

<h2>Your Submission:</h2>
<pre>
<% params[:product].each do |name, value| %>
  <%=h name.humanize %>: <%=h value %>
<% end %>
</pre>

<h2>Edit Product:</h2>
<% form_for :product, :url => product_path(@product), :html => { :method => :put } do |f| %>
  <%= render :partial => 'form', :locals => { :f => f } %>
  <%= submit_tag 'Resolve' %>
<% end %>

RSS Feed for Episode Comments 10 comments

1. chineseGuy Jul 18, 2007 at 00:21

Thanks!let me see


2. chineseGuy Jul 18, 2007 at 00:29

great!!thanks again!


3. Lisa Seelye Jul 18, 2007 at 00:58

Good show. Locking can be a real pain to understand and implement!


4. dudzjosh Jul 18, 2007 at 03:20

Sorry this is just a bit off topic just wondering what tab terminal software you are using?


5. Bounga Jul 18, 2007 at 04:39

@dudzjosh : I think he's using ITerm


6. vlad Jul 18, 2007 at 05:44

dudzjosh: he's using iTerm

hmm, it seems kind of hard to try to resolve the confict "behind the scenes" without keeping any additional information about the edits.

i think you can do something like a form with radio buttons to choose between the conflicting field(s), but that won't work in case of 2 concurrent changes to the same field, which brings me back to the manual approach. i'm starting to wonder if there's a better way to resolve these dependencies without additional record-keeping.


7. Ryan Bates Jul 18, 2007 at 07:33

@vlad, good point. You would need to store the history of the edits with acts_as_versioned or something so you can compare it with the new edits and see who changed what. Then it would be possible to see the two changes didn't overlap (one changed the price and the other changed the description) so it can be resolved behind the scenes.

Alternatively you could pass the model's attributes in hidden fields in addition to the editable fields. That way you have the last history without using act_as_versioned. That might be messy though.


8. vlad Jul 18, 2007 at 08:42

oh, so there's an acts_as_versioned? awesome.


9. Ryan Bates Jul 18, 2007 at 08:55

Yep, it's a plugin by Rick Olson:

http://svn.techno-weenie.net/projects/plugins/acts_as_versioned/


10. Eric Baker Jul 24, 2007 at 15:23

Ryan, Thanks for this! I have a question for some weird behavior I'm seeing:

In my controller I'm doing a model.reload as you've implemented it, and render a "conflict" action. In the controller, if I 'puts' on any of the model variables before and after the reload, I can see the change, but the form never reflects the change. Doing a 'puts' in the form writes out the pre-update model information.

My form is a bit different in that I'm using a form_tag and :id => model_name, but as I understand it, it should reload the model from the db, correct? I'm missing something simple.

Thanks in advance for a great site!


11. Eric Baker Jul 24, 2007 at 15:56

Ryan,

Ok, ignore me, found the problem, which is in my model definition.

Sometimes it just helps to talk. ;-)


12. vorsteuer guy Dec 20, 2008 at 09:26

Even it's an old one, it's a great one, and as always with every of my projects you seem to read my mind. Had a problem, found your screencast. Keep on going. Thx.


13. laser lipo prices Oct 18, 2009 at 03:33

Thanks for the great content!


14. Enterprise Data Management Works Nov 18, 2009 at 06:55

What is it all about?


15. Annie Slattery Nov 18, 2009 at 06:56

I wish I knew.


16. Golden Source Copy Nov 18, 2009 at 06:58

They are all posting html.


17. London It Doctor Nov 18, 2009 at 07:00

Great, thanks for sharing


18. discount links of london Feb 27, 2010 at 00:50

Faithful links of london ladies are always looking for discount links of london collections among UK, and we can get access to the discount collections like links of london bracelets and cheap links of london charms on the internet.


19. Gang Mar 30, 2010 at 03:46

Wow! It's very cool, thank you.


20. life experience degree Jun 30, 2010 at 22:47

Amazing one, i appreciate this work....


21. life experience degree Jul 29, 2010 at 00:14

Amazing one, i appreciate this work....


23. life experience degree Aug 10, 2010 at 03:02

Very nice Site number one topic Thanks you..


24. Air Jordan Spizike Aug 17, 2010 at 20:02

Thanks for the great content! It's very cool, thank you.


25. louis vuitton shoes Aug 26, 2010 at 21:02

Thanks for sharing your article. I really enjoyed it. I put a link to my site to here so other people can read it. My readers have about the same interets


26. snow boots Aug 31, 2010 at 01:14

Alternatively you could pass the model's attributes in hidden fields in addition to the editable fields.


27. levis belts Sep 01, 2010 at 21:02

Good article! Thank you so much for sharing this post.Your views truly open my mind.

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player
Give Back to Open Source