Filter blogs by:
- 2016 (185) See months Hide months
- Alexis Roos (4)
- Ali LeClerc (28)
- Anil Kumar (9)
- Anne Obendorf (6)
- Arun Gupta (49)
- Austin Gonyou (3)
- Benjamin Young (2)
- Bob Wiederhold (23)
- Brett Lawson (16)
- Cecile Le Pape (2)
- Cihan Biyikoglu (33)
- Damien Katz (3)
- David Maier (1)
- David Maitland (4)
- David Ostrovsky (1)
- Dipti Borkar (1)
- Don Pinto (36)
- Doug Laird (4)
- Dustin Sallings (8)
- Eric Lambert (1)
- Gareth Powell (1)
- Ilam Siva (4)
- J. Chris Anderson (12)
- James Nocentini (19)
- James Phillips (14)
- Jan Lehnardt (1)
- Jeff Morris (39)
- John Zablocki (16)
- Justin Michaels (2)
- Keshav Murthy (1)
- Ketaki Gangal (1)
- Kirk Kirkconnell (11)
- Koji Kawamura (1)
- Laura Czajkowski (22)
- Laurent Doguin (26)
- MC Brown (4)
- Manuel Hurtado (1)
- Mark Nunberg (10)
- Martin Esmann (10)
- Marty Schoch (4)
- Matt Ingenthron (8)
- Matthew Groves (7)
- Matthew Revell (32)
- Michael Nitschinger (14)
- Nic Raboy (45)
- Pasin Suriyentrakorn (1)
- Patrick Galbraith (5)
- Perry Krug (10)
- Philipp Fehre (2)
- Pranav Mayuram (6)
- Prasad Varakur (2)
- Qi Zhu (1)
- Raghavan Srinivas (7)
- Roi Katz (3)
- Sandhya Krishnamurthy (1)
- Sean Lynch (3)
- Sergey Avseyev (8)
- Shane Johnson (28)
- Simon Baslé (13)
- Steve Yen (2)
- Tim Wong (2)
- Todd Greenstein (12)
- Tom Rosenfeld (1)
- Traun Leyden (1)
- Trond Norbye (12)
- Volker Mische (3)
- Wayne Carter (7)
- Will Gardella (1)
- William Hoang (41)
- See all
- See fewer
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 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 -
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 :
- Use the get-and-lock API to retrieve a value for a given key and lock that key
- The application now has exclusive control over the document
Obtaining a optimistic lock in Couchbase Server
Obtaining a lock in Couchbase Server consists of the following steps :
- 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:
- 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.
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.