Optimistic Locking in Spring Boot

09 / Sep / 2022 by aditya.singh1 0 comments

Overview

We know that for large-scale software applications that handle a large number of database transactions, implementing a concurrency management mechanism is essential so that we can handle multiple database calls simultaneously and effectively without any data loss.

One of the ways to implement concurrency control is the optimistic locking mechanism provided by Java Persistence API.

Contrary to pessimistic locking, optimistic locking doesn’t apply locks on the database and hence reduces the isolation level of the system and increases the throughput capacity of the software. Also, there is no chance of deadlock in this like in pessimistic locking.

It allows transactional conflicts to occur and detects them while committing the transaction, and then we can handle the flow according to our use case.

Implementation of Optimistic Locking

The implementation of optimistic locking is simple. It can be implemented using a new property version in the entity (annotating it with @Version). Although there have been multiple implementations of this attribute, the most effective and widely used is a simple integer type numeric counter type version whose value will be auto-incremented each time we update the data. We also need to ensure that the entity’s state is not getting fetched from the cache for this.

Let’s try to understand the use of the version attribute.

1) Both investor1 and investor2 will fetch the same data with, let’s say version=1,

2) investor1 will be saved first, and the version will be automatically updated to 2(vesrion=version+1).

3) now, when we try to save investor2, the query similar to the following query will be run

          Update investor 

          Set version=2, firstName=’XYZ’

          Where uuid=randomUuid

          and version=1

 4) now as we know, that version is already updated by investor1 while saving, so no row will be fetched while updating investor2, and optimisticLockingException will be thrown for investor2 hence preventing the silent data loss of investor1.

Handling of optimisticLockingException:

There are mainly two ways to handle this exception:

1) In the catch block, we can fetch the data again for investor2, then try to make changes in the data if possible and then try saving the data again.

2) The Second option could be that we just show a message to the user that either some other user updated the data or an error has occurred and ask the user to update the data again.

So depending on our use cases, we can implement either of the above methods.

Conclusion

Although optimistic locking cannot be implemented to handle all types of concurrency issues, whether to implement optimistic locking depends on a case-by-case basis. For example, it can be used where there are more read transactions than written transactions. It can be used where we don’t want a single transaction to acquire the lock on a database or, in fact, where we can afford the loss of data. Also, like in pessimistic locking, it doesn’t put a lock on the data, so it can be used where we put data into a detached state after fetching it, but at the same time, needless to say, pessimistic locking provides greater data integrity.

 


 

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *