NoSQL Zone is brought to you in partnership with:

Don Pinto is a Product Marketing Manager with experience in cloud and database technologies. Don is a DZone MVB and is not an employee of DZone and has posted 94 posts at DZone. You can read more from them at their website. View Full User Profile

Optimistic or Pessimistic Locking: Which One Should You Pick?

12.05.2012
| 3722 views |
  • submit to reddit

Assume that Alice and Joe both read the same data item from Couchbase Server, then they both changed the data, and then both tried to write the new versions back to the database. Whose changes should be saved? Alice’s? Joe’s? Neither? A combination?

Developers use locking to serialize access to shared data items. But which locking scheme should you pick for your application - optimistic or pessimistic?

 

In this blog, I am going to explain the differences between pessimistic and optimistic locking, and discuss about the optimistic and pessimistic locking APIs that you can use in Couchbase Server to control concurrent access to your data.

Optimistic Locking in Couchbase Server

Let’s assume we are building an online wikipedia - like application using Couchbase Server: users can update an article and add newer articles. Let’s assume Alice is using this application to edit an article on ‘bicycles’ to correct some information. Alice opens up the article and makes those changes but before she hits save, she gets distracted and walks away from her desk. In the meantime, let’s assume Joe notices the same error in the bicycle article and wants to correct the mistake.

If optimistic locking is used in the application, Joe can edit the article and save his changes. When Alice returns and wants to save her changes, either Alice or the application will want to handle the latest updates before allowing Alice’s action to change the document. Optimistic locking takes the “optimistic” view that data conflicts due to concurrent edits occur rarely, so it’s more important to allow concurrent edits.

 

Pessimistic Locking in Couchbase Server

Now let’s assume that your business process requires exclusive access to one or more

documents or a graph of documents. Referring to our previous example, when Alice is editing the document she does not want any other user to edit the same document. If Joe tries to open the page, he will have to wait until Alice has released the lock.

 

With pessimistic locking, the application will need to explicitly get a lock on the document to guarantee exclusive user access. When the user is done accessing the document, the locks can be removed either manually or using a timeout.

 

So which one should you pick?

 

The answer is that, there is no correct answer - it depends. You should pick your locking scheme based on your application requirements.

Unless you expect a document to be heavily contended, optimistic locking is going to be much lower overhead than pessimistic locking - grab the item you need, update it quickly and attemp to apply it. If some other actor in the system beat you to it, you can just retry till you succeed.

With pessimistic locking, you can get exclusive access to a given item - no other thread can access the item while it is locked. You need to be make sure you release the lock during failures. Imagine, I have the cereal object and won't give it up until I get the milk object. But you have the milk object and won't give it up until you get the cereal object. Timeouts can be used to possibly break deadlocks or to deal with clients who fail to release the lock. 

For simplicity's sake, users might pick the same locking strategy across their application. This works well if the access requirements of all the different objects across your application are the same but in reality, this is not the case - different application objects have different access requirements. For example, in the case of social games -

 

  1. Character and player inventory information is heavily accessed during gameplay, requiring fast read-write access. First choice: use optimistic locking; next choice, pessimistic locking.
  2. Player accounts and preferences are read during player login or at the start of a game but not frequently updated. Optimistic locking would work well here too.

 

Obtaining a pessimistic lock in Couchbase Server

Obtaining a lock in Couchbase Server consists of the following steps :

  1. Use the get-and-lock API to retrieve a value for a given key and lock that key
  2. The application now has exclusive control over the document

Obtaining an optimistic lock in Couchbase Server

Obtaining a lock in Couchbase Server consists of the following steps :

  1. Use the check-and-set (CAS) API to retrieve a CAS revision number

Releasing a lock in Couchbase Server

Perform these steps to manually release a lock:

  1. Use CAS to modify the value and release the lock

Behind the scenes of CAS

CAS operation is a simple concept which can be used to build more advanced concurrency control mechanisms. CAS determines if an object has been updated by another client between the time it was initially read and the time the save was attempted. If the object is modified by another client, an error is raised and the application has to re-read the value and retry the operation. If objects are not in high contention, the transformation of the data is idempotent and retrying the operation is easily accomplished without too much wasted work, optimistic locking is a good solution that provides high performance in the average case.

A common way of interacting with CAS involves a CAS loop as shown in the community developed go memcached client.

For example: Imagine there are 3 clients as shown in the interaction diagram below. All of the three clients attempt to update object X using CAS - each client succeeds, one at a time.

You didn't release the lock, let Couchbase do it for you

When you perform a get-and-lock operation you provide an expiration for the lock as a parameter. The default amount of time a key can be locked is 15 seconds. After 15 seconds, if you don't release the lock manually, Couchbase releases it automatically.

Final Thoughts

Optimistic locking might not be the best solution for every situation. While some use-cases work well with optimistic locking, others might need stricter schemes like pessimistic locking.

Locking might not be good for all cases - your application can have a problem if there is a lock contention. A thread can hold a lock and be de-scheduled by the OS. Then all the threads that want to acquire this lock will be blocked. One option is to avoid locking altogether where possible by using atomic operations. These API's can be very helpful on heavily contested data.

However, if you really need locking and feel that optimistic locking covers most of your applications' use-cases, optimistic locking using CAS in Couchbase Server is so easy to implement there's no reason you shouldn't try.



Published at DZone with permission of Don Pinto, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)