[TIL-1] Optimistic locking vs Pessimistic locking

davidasync
4 min readNov 18, 2020

Usually, I messed up with fundamental things although it’s already taught at the college. Because as software engineer usually I am already pampered by high-level abstraction.

At glance, I already forgot about pessimistic locking and optimistic locking. But after reading at several resources, turns out I’ve implemented that mechanism to my previous applications but I didn’t know that is called pessimistic locking or optimistic locking or whatever locking.

In this article, I’m compiling several sources to get to know about Pessimistic Lock vs Optimistic Lock.

Why Lock?

We use locks to protect data integrity and atomicity in concurrent applications where a record could get read/write requests.

Let’s imagine we have an online store system without locking.

We have a table that is called Products, it has an attribute that is called Stock.

Assume a product called Soap has 15 stock remaining

One day, there are 2 users that buy soap simultaneously. And simultaneously update the table.

User Foo -> read soap’s stock = 15 -> buy 10 soaps -> update the soap’s stock to 5

User Bar -> read soap’s stock = 15 -> buy 8 soapss -> update the soap’s stock to 7

And finally the soap’s stock is updated to 7. This is one of the currency problems called Lost Update Problem.

Optimistic Lock

Optimistic Locking is a strategy where you read a record, take note of a version number (other methods to do this involve dates, timestamps, or checksums/hashes), and check that the version hasn’t changed before you write the record back. When you write the record back you filter the update on the version to make sure it’s atomic. (i.e. hasn’t been updated between when you check the version and write the record to the disk) and update the version in one hit.

If the record is dirty (i.e. different version to yours) you abort the transaction and the user can restart it.

In the above case, if we apply optimistic locking.

User Foo -> read the soap’s stock = 15 with version 1 -> buy 10 soap -> update the soap’s stock to 5 and version to version 2 where the version is 1

User Bar -> read the soap’s stock = 15 with version 1-> buy 8 soaps -> update the soap’s stock to 7 and version to version 2 where the version is 1 because the version already updated to version 2 the record will be failed to be updated, therefore we can try to retry the operation

User Bar -> read the soap’s stock = 5 with version 2 -> buy 8 soaps -> give the information to user that the soap’s stock is insufficient

Pessimistic Locking

Pessimistic Locking is when you lock the record for your exclusive use until you have finished with it. It has much better integrity than optimistic locking but requires you to be careful with your application design to avoid Deadlocks.

In the above case, if we apply pessimistic locking.

User Foo -> read the soap’s stock = 15 -> buy 10 soaps -> acquire the lock -> read the soap’s stock = 15 to update -> update the soap’s stock to 5 -> release the lock

User Bar -> read the soap’s stock = 15 -> buy 8 soaps -> acquire the lock -> acquire the lock failed due to acquired by other User -> waiting until the lock is released -> acquire the lock -> read the soap’s stock = 5 to update -> update failed due to insufficient stock -> release the lock

Conclusion

Optimistic Locking is when you check if the record was updated by someone else before you commit the transaction. Pessimistic locking is when you take an exclusive lock so that no one else can start modifying the record.

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 have heavily contended, optimistic locking is going to be much lower overhead than pessimistic locking, grab the item you need, update it quickly and attempt to apply it. If some other actors 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 sure you release the lock during failures.

For simplicity's sake, users might pick the same locking strategy across their applications. 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

References

https://blog.couchbase.com/optimistic-or-pessimistic-locking-which-one-should-you-pick

--

--

davidasync

The Joy of discovery is one of the best things about being a software developer ~ Eric Elliott