pessimistic locking

Hey,

I've been trying to figure out how to use pessimistic locking. So far I've found this:

table.transaction do   row = table.find(:first, :lock=>true)   row.col = blah   row.save! end

I'm not that familiar with SQL or this activerecord layer so it's a little bit confusing. First of all, is that how you use it? Secondly, this is what I'm trying to do:

two actions:

def edit   # render my form end

def save   # save my form end

When a user clicks on my link_to to go to "edit", I want to lock 1 or more rows (depending on a special # that identifies groups of rows in my table) So if this number is 5, then I want to lock all rows with "special"=5. I want it to be locked from editing, not from reading.

What is the exception that gets thrown if someone is already editing it? So I can do something like:

if being_edited(exception)   flash[:notice] = "Try again later."   redirect_to_index end

Also, how do I unlock the rows when a user closes the browser, or changes to a different page, or saves the form?

Thanks for the help!

Hey,

I've been trying to figure out how to use pessimistic locking. So far I've found this:

table.transaction do row = table.find(:first, :lock=>true) row.col = blah row.save! end

I'm not that familiar with SQL or this activerecord layer so it's a little bit confusing. First of all, is that how you use it? Secondly, this is what I'm trying to do:

Yup that's how it's used.

two actions:

def edit # render my form end

def save # save my form end

When a user clicks on my link_to to go to "edit", I want to lock 1 or more rows (depending on a special # that identifies groups of rows in my table) So if this number is 5, then I want to lock all rows with "special"=5. I want it to be locked from editing, not from reading.

This sort of 'locking' is completely different from locking as the database understands it. (If a row is locked and someone else tries to lock it that process will block until the lock is released or the database gets bored of waiting).

You would usually implement this by having a locked_by attribute on the rows that you set when someone starts editing a row (the place were database level locking and so on comes it is how you ensure that if two people try to start editing a rows they don't both end up thinking they've got the lock).

What is the exception that gets thrown if someone is already editing it?

So I can do something like:

if being_edited(exception) flash[:notice] = "Try again later." redirect_to_index end

Also, how do I unlock the rows when a user closes the browser, or changes to a different page, or saves the form?

Stick a timestamp with the lock and check for outdated locks (either on a timer or perhaps just whenever you need to see if the lock is set).

Fred

Ok Fred, thanks for the tips. I will try to implement it tomorrow!

Justin,

It might be helpful if you explain what you're really trying to do. Generally speaking, pessimistic locking makes for a really bad user experience. Especially when the users aren't physically located in the same room.

Every web application I'm aware of either uses a "last write wins" scenario or at most use some form of optimistic locking. Locking a record on the "chance" that two users "might" update the record at the same time is generally not the best approach. A better approach is a "detect and recover" scenario. This allows any number of users to open and edit the record. These conflicts can be caught and dealt with on a case-by-case bases using optimistic locking.

I would recommend looking into ActiveRecord's support for optimistic locking rather than resorting to pessimistic locking. Just something to think about.

Justin To wrote: