Optimistic Locking in JPA with Version Annotation

Farzin Pashaee
Technology Times

--

Concurrency in a database refers to DBMS’s capacity to manage many concurrent activities or transactions from various users or processes without jeopardizing the integrity or consistency of the data. Considering that many applications demand concurrent access to the database from several users or processes, Concurrency is an important component of contemporary databases.

Attempting to read from or write to the database at the same time may cause several issues to emerge including:

  • Data Consistency — A transaction processing data in the database simultaneously can cause problems with the accuracy and validity of the data.
  • Deadlocks — As a result of 2 or multiple transactions trying to change and access the same resource in the database a deadlock can happen. It simply is like different processes blocking each other from the resources they need causing an infinite wait.
  • Performance — Too many locking and transaction serialization can play a major role in database response time, triggered by concurrent access to the Data in the Databases.

The good news is there are solutions out of the box coming with Database products that you can use to overcome these issues using Locking, Isolation Levels, time stamping, or Multiversion concurrency control (MVCC).

In this article, we will use JPA version annotation to help overcome some of these issues by taking advantage of Optimistic Locking.

Optimistic vs. Pessimistic Locking

Based on the nature of the data you are working with you can pick the proper approach to do the locking in Database records.

  • Optimistic Locking — In this method Multiple users can attempt to change the same record simultaneously using optimistic locking without being made aware of the other users’ attempts and only when The other users attempt to commit their concurrent updates They will be alerted that a conflict exists.
  • Pessimistic Locking — The pessimistic locking method forbids concurrent record updates. A lock is applied to a record as soon as one person begins to update it and users who attempt to update this record are alerted that an update is currently being made by another user.

Optimistic Locking with @Version

Using @Version is pretty easy. you just need to have a field in your Entity class that has the annotation and it is one of the following types: int, Integer, long, Long, short, Short, java.sql.Timestamp.

@Entity
public class Product {

@Id
private Long id;
private String name;
private BigDecimal price;

@Version
private Integer version;

}

Having this entity with a version field now you have already enabled Optimistic locking on this entity. This means you will have easy read access to the record in the database. In case any concurrent update takes place, the latest attempt will receive an OptmisticLockException because the version holding in the entity is older than the newly changed version managed by the database.

Be aware that optimistic locking is supported by persistence providers for entities without a version field as well If you are explicitly making the database query with an optimistic lock setup.

We have two different optimistic lock modes available from JPA:

  • OPTIMISTIC — For all entities with a version attribute, you will get an optimistic read lock.
  • OPTIMISTIC_FORCE_INCREMENT — just like the OPTIMISTIC with an additional increment in the version attribute value.

Here are some examples of how to use it.

entityManager.find(Product.class, id, LockModeType.OPTIMISTIC);

Or when you are using Spring Data Repository:

@Lock(LockModeType.OPTIMISTIC_FORCE_INCREMENT)
@Query("SELECT p FROM Product p WHERE p.Id = ?1")
public Optional<Product> getProductById(Long id);

I hope this article helped you, and please support me by applauding 👏 for the story. If you don’t know how it works, it’s just like this:

Or buy me a coffee here!

--

--