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: