DEV Community

loading...
Cover image for Optimistic lock on Ruby on Rails

Optimistic lock on Ruby on Rails

marcelobarreto profile image Marcelo Barreto ・3 min read

What are locks and why using it?

Locks are required for concurrency in multi-user scenarios (where one or more users could modify one register in the same time), and you need to avoid data to be overriden without the user knowing about that one new version of the register they're updating was updated some seconds ago by another user.

Locks

The example created for this article is available at Github

Optimistic lock

You can use optimistic lock when you can assume that users are allowed to edit a register on the same time. In order to this, we need to add a versioning to the table that we'll need to lock.

To our examples, I've created a model called Article, and the columns are title:string text:text version:integer. By default, if you call our version column as lock_version, Rails will handle the optimistic lock for you automatically, but, for this example let's use a different name so you can see behind the magic.

Let's update our Article model to be as follows:

Article Model

Now, on our view, let's fix one quick thing. We should send back to the server which version the user is updating, but you should not show this to the user, so let's update the view to hide our version input field. And for now, we should have something more or less like this:

Article form

Let's see how the optimistic lock works for real!

First, let's create a new article and then, let's open two tab's on our browser to update the article on the same time.

Alt Text

On the first tab, I'll update the title and hit update article, while in the second, after the first tab finishes to load, I'll update the title too.

Stable object error

Wow, an error was raised, that was expected. But first, let me explain one thing: our tabs were holding our version number as 1, and after we updated the first tab, it was increased to 2, and on the second tab, we're trying to update the version as 1, in other words, we're trying to update a stale object. Let's fix this and give a better error message to the user:

Example

Disclaimer: I know updating Rails default methods is not the best approach, but fits well for this example

Let's try to repeat the same scenario again and see how it should work now:

Alt Text

Fair enough... But let's polish this a little bit more.

On our controller, let's return the newest article's version doing the following:

Alt Text

On our form, let's update the view to show the fresh version, so the user would be able to compare the new article to the previous version, and let's increase the version into the new version + 1, otherwise, the user will be locked (bad joke?).

OMG

Now, the user should be seen this:

New version available

And when the user hits the update again, it'll be able to update the registry, finally 🙌😌

Finally update registry

Final thoughts

Rails is fantastic, and how it handle lots of problems for you is incredible. Sometimes we don't know some of these awesome features that Rails deliver to us. This is one thing that now should be available on your toolbelt if you didn't know about it before. I hope that you enjoyed this article and I'm eager to hear you, what are your thoughts? Have you ever used this? Why? I'd love to hear you, please comment bellow and share with your friends.

References

https://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html

Discussion (0)

pic
Editor guide