# When to use optimistic locking?

**URL:** <https://www.ruby-forum.com/t/when-to-use-optimistic-locking/60040>\
**Category:** Rails\
**Created:** [May 9, 2006, 6:26pm UTC](https://www.ruby-forum.com/t/when-to-use-optimistic-locking/60040 "2006-05-09T18:26:45Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jtoy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f475e1/32.png) [@jtoy](https://www.ruby-forum.com/u/jtoy)\
**Post date:** [May 9, 2006, 6:26pm UTC](https://www.ruby-forum.com/t/when-to-use-optimistic-locking/60040/1 "2006-05-09T18:26:45Z")

</div>

Hi All,

I’m having some trouble deciding when and how to implement optimistic  
locking.

Let’s say I have a multiuser Rails app, and let’s say it stores,  
among other things “vital” customer information.

The standard methods created by the Rails generate scaffold script  
look like this:

def edit  
@customer = Customer.find(params[:id])  
end

def update  
@customer = Customer.find(params[:id])  
if @customer.update\_attributes(params[:customer])  
flash[:notice] = ‘Customer was successfully updated.’  
redirect\_to :action =\> ‘show’, :id =\> @customer  
else  
render :action =\> ‘edit’  
end  
end

What if I want to guard against 2 people simultaneously updating the  
same customer record? How would I go about doing this? I can’t find  
any examples online, and I’m a bit lost.

Thanks,

: )

Jason

---

<div class="post-metadata">

**Author:** ![jtoy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f475e1/32.png) [@jtoy](https://www.ruby-forum.com/u/jtoy)\
**Post date:** [May 9, 2006, 6:45pm UTC](https://www.ruby-forum.com/t/when-to-use-optimistic-locking/60040/2 "2006-05-09T18:45:15Z")

</div>

> What if I want to guard against 2 people simultaneously updating  
> the same customer record? How would I go about doing this? I can’t  
> find any examples online, and I’m a bit lost.

Well, first of all, you need a lock\_version column in your model  
(table) (or override it with the “set\_locking\_column” method). If a  
record has been changed by someone else, Rails will throw a  
StaleObjectError, you need to trap this error and handle it  
appropriately (present the user with a dialog confirming to update  
the record anyway or cancel it). It’s up to you to find a way to  
handle the error.

Best regards

Peter De Berdt

---

<div class="post-metadata">

**Author:** ![jtoy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f475e1/32.png) [@jtoy](https://www.ruby-forum.com/u/jtoy)\
**Post date:** [May 9, 2006, 8:02pm UTC](https://www.ruby-forum.com/t/when-to-use-optimistic-locking/60040/3 "2006-05-09T20:02:55Z")

</div>

Peter De Berdt wrote:

> > What if I want to guard against 2 people simultaneously updating  
> > the same customer record? How would I go about doing this? I can’t  
> > find any examples online, and I’m a bit lost.
> 
> Well, first of all, you need a lock\_version column in your model  
> (table) (or override it with the “set\_locking\_column” method). If a  
> record has been changed by someone else, Rails will throw a  
> StaleObjectError, you need to trap this error and handle it  
> appropriately (present the user with a dialog confirming to update  
> the record anyway or cancel it). It’s up to you to find a way to  
> handle the error.
> 
> Best regards
> 
> Peter De Berdt

Thanks Peter, but in the scaffold generated CRUD code, the model state  
is lost between the “edit” and “update” calls. – the StaleObjectError  
will never be thrown.

: )

Jason

---

<div class="post-metadata">

**Author:** ![jtoy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f475e1/32.png) [@jtoy](https://www.ruby-forum.com/u/jtoy)\
**Post date:** [May 9, 2006, 8:18pm UTC](https://www.ruby-forum.com/t/when-to-use-optimistic-locking/60040/4 "2006-05-09T20:18:10Z")

</div>

Jason T. wrote:

> Hi All,
> 
> I’m having some trouble deciding when and how to implement optimistic  
> locking.
> 
> Let’s say I have a multiuser Rails app, and let’s say it stores,  
> among other things “vital” customer information.
> 
> The standard methods created by the Rails generate scaffold script  
> look like this:
> 
> def edit  
> @customer = Customer.find(params[:id])  
> end
> 
> def update  
> @customer = Customer.find(params[:id])  
> if @customer.update\_attributes(params[:customer])  
> flash[:notice] = ‘Customer was successfully updated.’  
> redirect\_to :action =\> ‘show’, :id =\> @customer  
> else  
> render :action =\> ‘edit’  
> end  
> end
> 
> What if I want to guard against 2 people simultaneously updating the  
> same customer record? How would I go about doing this? I can’t find  
> any examples online, and I’m a bit lost.
> 
> Thanks,
> 
> : )
> 
> Jason

The more I think about it, there doesn’t seem to be a way to take  
advantage of Active Record’s optimistic locking when using the standard  
scaffold generated CRUD approach because the model state is lost between  
the call to “edit” and the subsequent call to “update”. – The  
ActiveRecord::StaleObjectError will never be thrown.

Do you have to manually track the value of the lock\_version column?

There must be a more elegant solution.

I must be missing something. I just can’t figure out what.

- Jason

---

<div class="post-metadata">

**Author:** ![jtoy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f475e1/32.png) [@jtoy](https://www.ruby-forum.com/u/jtoy)\
**Post date:** [May 9, 2006, 8:43pm UTC](https://www.ruby-forum.com/t/when-to-use-optimistic-locking/60040/5 "2006-05-09T20:43:53Z")

</div>

On May 9, 2006, at 11:18 AM, Jason T. wrote:

> The more I think about it, there doesn’t seem to be a way to take  
> advantage of Active Record’s optimistic locking when using the  
> standard  
> scaffold generated CRUD approach because the model state is lost  
> between  
> the call to “edit” and the subsequent call to “update”. – The  
> ActiveRecord::StaleObjectError will never be thrown.
> 
> Do you have to manually track the value of the lock\_version column?

Yes.

> There must be a more elegant solution.

Wrap up the lock\_version handling by passing it in session, crypted  
form param, or similar.

> I must be missing something. I just can’t figure out what.

A well-tested patch? 🙂

Michael S. did quite a bit of work on an alternate scaffolding  
toolset that includes conflict resolution. See his Boilerplate lib:  
[http://www.schuerig.de/michael/boilerplate/](http://www.schuerig.de/michael/boilerplate/)

Best,  
jeremy

---

<div class="post-metadata">

**Author:** ![jtoy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f475e1/32.png) [@jtoy](https://www.ruby-forum.com/u/jtoy)\
**Post date:** [May 9, 2006, 8:56pm UTC](https://www.ruby-forum.com/t/when-to-use-optimistic-locking/60040/6 "2006-05-09T20:56:10Z")

</div>

Kevin O. wrote:

> On Tuesday, May 09, 2006, at 8:18 PM, Jason T. wrote:
> 
> > > look like this:  
> > > else  
> > > : )
> > 
> > removed\_email\_address@domain.invalid  
> > [http://lists.rubyonrails.org/mailman/listinfo/rails](http://lists.rubyonrails.org/mailman/listinfo/rails)
> 
> It works. I think it puts a hidden text field with the value of the  
> lock\_version in the form. When you go to save it, it compares the value  
> to the one in the database. If the one in the database is different,  
> then someone has modified the record. Once saved, the value is  
> incremented.
> 
> So the state of the record is retained. I think AR is smart enough to  
> know what to do with this without adding additional code, which is why  
> they call it a ‘magic’ column.
> 
> \_Kevin

Hi Kevin,

I just double checked. – There doesn’t seem to bee any hidden field.

- Jason

---

<div class="post-metadata">

**Author:** ![jtoy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f475e1/32.png) [@jtoy](https://www.ruby-forum.com/u/jtoy)\
**Post date:** [May 9, 2006, 8:34pm UTC](https://www.ruby-forum.com/t/when-to-use-optimistic-locking/60040/7 "2006-05-09T20:34:11Z")

</div>

On Tuesday, May 09, 2006, at 8:18 PM, Jason T. wrote:

> > look like this:  
> > else  
> > : )
> 
> removed\_email\_address@domain.invalid  
> [http://lists.rubyonrails.org/mailman/listinfo/rails](http://lists.rubyonrails.org/mailman/listinfo/rails)

It works. I think it puts a hidden text field with the value of the  
lock\_version in the form. When you go to save it, it compares the value  
to the one in the database. If the one in the database is different,  
then someone has modified the record. Once saved, the value is  
incremented.

So the state of the record is retained. I think AR is smart enough to  
know what to do with this without adding additional code, which is why  
they call it a ‘magic’ column.

\_Kevin

---

<div class="post-metadata">

**Author:** ![jtoy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f475e1/32.png) [@jtoy](https://www.ruby-forum.com/u/jtoy)\
**Post date:** [May 9, 2006, 9:22pm UTC](https://www.ruby-forum.com/t/when-to-use-optimistic-locking/60040/8 "2006-05-09T21:22:22Z")

</div>

Jeremy K. wrote:

> On May 9, 2006, at 11:18 AM, Jason T. wrote:
> 
> > The more I think about it, there doesn’t seem to be a way to take  
> > advantage of Active Record’s optimistic locking when using the  
> > standard  
> > scaffold generated CRUD approach because the model state is lost  
> > between  
> > the call to “edit” and the subsequent call to “update”. – The  
> > ActiveRecord::StaleObjectError will never be thrown.
> > 
> > Do you have to manually track the value of the lock\_version column?
> 
> Yes.
> 
> > There must be a more elegant solution.
> 
> Wrap up the lock\_version handling by passing it in session, crypted  
> form param, or similar.
> 
> > I must be missing something. I just can’t figure out what.
> 
> A well-tested patch? 🙂
> 
> Michael S. did quite a bit of work on an alternate scaffolding  
> toolset that includes conflict resolution. See his Boilerplate lib:  
> [http://www.schuerig.de/michael/boilerplate/](http://www.schuerig.de/michael/boilerplate/)
> 
> Best,  
> jeremy

Thanks Jeremy. – I’m off to check out Boilerplate lib right now.

- Jason
