If our data has concurrent access , then some kind of locking mechanism should be there to prevent data corruption.JPA supports two types of locking mechanisms. This chapter is discussing about the various locking mechanisms in JPA as of JPA2.0.
Locking in JPA
There are two locking strategies supporting by JPA.
They are :
- Optimistic Locking
- Pessimistic Locking
Optimistic locking is the most common style of locking mechanism.By default ,Optimistic locking mechanism is using by all persistence providers. For optimistic locking the entity should have a version attribute. The type of the field is preferably int. The attribute should be annotated with @Version or should be specified using element in case of XML mapping.The version attributevalue will be automatically changing by the JPA provider at each commit. Before each commit JPA checks for the version value . If a mismatch occurs between the version values in the updated object and existing one in the database , then OptimisticLockException will be thrown and the original transaction will be rolled back.
Consider an example:- Suppose one user accessed an object and updating it. Assume the version value is 1.During this time ,assume another user accessed the same object , edited and committed.So this commit will change the version field value in database automatically .Suppose now the database row contains 2 as version value. Now the first user is trying to commit the updated object. So the commit operation will check for version attribute. Here the version numbers are different . So the exception will be thrown and transaction will be rolled back. We can catch the exception and can handle appropriately.
In case of pessimistic locking , the persistence provider makes a transaction which obtains a lock on the data it is handling till the end of the transaction.So other transactions cannot modify the data till the lock released.
The lock() method of EntityManager is using for pessimistic locking.
The lock request mode can be either Pessimistic Read(LockModeType.PESSIMISTIC_READ needs to be passed as argument) or Pessimistic Write (LockModeType.PESSIMISTIC WRITE needs to be passed as argument ) or Pessimistic Increment (LockModeType.PESSIMISTIC_FORCE_INCREMENT needs to be passed as argument)
The lock() method should be called from an active transaction. Otherwise TransactionRequiredException will be thrown.
Pessimistic Locking Timeouts
The maximum time the persistence provider need to get the lock may be specified using the property javax.persistence.lock.timeout. If lock is not acquired within this time , LockTimeoutException will be thrown.
Lock Modes can be specified to enhance the level of optimistic locking or to enable the pessimistic locking.The LockModeType enum has the constants to specify the lock modes.
- NONE -:No lock
- OPTIMISTIC -: Obtains the optimistic read locks for all entities with version attribute.
- OPTIMISTIC_FORCE_INCREMENT -: Obtains the optimistic read locks for all entities with version attribute and increments the version attribute value.
- PESSIMISTIC_READ -: Obtains long term lock on the data.Other transactions can read the data, but cannot modify or delete the same data.
- PESSIMISTIC_WRITE -: Obtains long term lock on the data. Other transactions cannot read , or update or delete the same data.
- PESSIMISTIC_FORCE_INCREMENT -: Obtains long term lock on the data and increments the version attribute. Other transactions cannot update or delete the same data.
- READ -: Synonym of OPTIMISTIC
- WRITE -: Synonym of OPTIMIC_FORCE_INCREMENT
See Related Discussions
JPA Mapping Schemes