AdiSingh blog ya'll

View on GitHub

Datalocking in Rails // 2-7-15

I've been going over Rails 4 guide by Obie Fernandez, and I'm really trying to bring to light things that I've overlooked with ActiveRecord. I frequently have my go-to's, but I really want a thorough understanding of everything there is to offer.

A cool concept I learned today through this book as well as this video was the concept of Data locking.

So let's get into it..

What is Datalocking?

Datalocking is a term to describe techniques that prevent multiple concurrent users of an app from updating + overwriting a record. Matt accesses the venue page and wants to change a detail. Sean does the same. And it's 9:45pm. Say Matt updates the page before Sean. Datalocking will prevent Sean from overwriting the venue page.

There's two types of Datalocking supported by ActiveRecord: optimistic and pessimistic.

Look on the bright side

Optimistic Loading resolve collision if they occur. What I mean by that is that the locking mechanism is occuring provided something triggers it.

class AddLockVersionToVenues < ActiveRecord::Migration
 def change
  add_column :venues, :lock_version, :integer, default:0
 end

end

You add the lock version column to the table you want optimistic loading on. Think of the lock_version property of the version of the record you have. Each time you update the Bada-Bing (Sopranos reference ahem) record, the lock_version will increment.

Back to our favorite buffoons. So let's say two concurrent users loaded up that record. Each of them are on the edit page and want to make an update. But John made it first, the lock_version will increment. Now the record has been updated in the database, with a +1 lock_version

But then where does that leave Sean ? He's clinging onto a Stale object. If he tries to update the Bada Bing , then a ActiveRecord::StaleObjectError shall be raised.

The way to deal with this when using optimistic loading is to have a rescue statement in the controller.

A couple things to note here:

Glass half empty

Or is it? You don't have to modify your table at all. Here, you're taking advantage of the Database's built-in locking and transaction mechanisms.

Transactions exist so you can sync up multiple database operations in a single 'all or nothing' operation. Whatever is within the transaction block is not visible to the outside, and ALL the changes take effect at the completion of the block.

Jacking this example from railsguides:

Account.transaction do
 # select * from accounts where name = 'shugo' limit 1 for update
 shugo = Account.where("name = 'shugo'").lock(true).first
 yuko = Account.where("name = 'yuko'").lock(true).first
 shugo.balance -= 100
 shugo.save!
 yuko.balance += 100
 yuko.save!
end

What anime did they find these names? Anyway, the rows returned by the SQL query (in this case a AR method that's distilled down to it's corresponding query) will be locked. Upon completion of the transaction, the locked state of the record will end.

To note