0
I have competition problems in my system, I need to insert the lock pessimistic because users access and save at the same time, causing bizarre errors in the result.
0
I have competition problems in my system, I need to insert the lock pessimistic because users access and save at the same time, causing bizarre errors in the result.
1
You can use the method lock(Object, LockModeType)
of EntityManager
. The way of use is this:
AlgumaEntidade x = ...;
EntityManager em = ...;
em.lock(x, LockModeType.PESSIMISTIC_WRITE);
To bring an entity from the database already with the lock pessimistic, use the method find
who has a LockModeType
as a parameter:
EntityManager em = ...;
AlgumaEntidade x = em.find(AlgumaEntidade.class, pk, LockModeType.PESSIMISTIC_WRITE);
The method refresh
, that updates the state of the entity when reread it from the database, also has an overload with LockModeType
:
AlgumaEntidade x = ...;
em.refresh(x, LockModeType.PESSIMISTIC_WRITE);
The objects Query
(and consequently, TypedQuery
and StoredProcedureQuery
) also has pessimistic lock support through the method setLockMode(LockModeType)
:
String jpql = ...;
Query q = em.createQuery(jpql);
q.setLockMode(LockModeType.PESSIMISTIC_WRITE);
As are the other methods of Query
, he can be chained:
String jpql = ...;
AlgumaEntidade x = em.createQuery(jpql, AlgumaEntidade.class)
.setLockMode(LockModeType.PESSIMISTIC_WRITE)
.setParameter(1, "blabla")
.getSingleResult();
The annotation NamedQuery
also has a field lockMode
optional.
The EntityManager
also has a method getLockMode(Object)
which can be used to find out what type of lock that is being applied to some entity. The Query
also has a method getLockMode()
that gets the LockModeType
which applies to Query
.
The Enum LockModeType
has the following elements: NONE
, OPTIMISTIC
, OPTIMISTIC_FORCE_INCREMENT
, PESSIMISTIC_FORCE_INCREMENT
, PESSIMISTIC_READ
, PESSIMISTIC_WRITE
, READ
and WRITE
.
The READ
is a synonym for OPTIMISTIC
and the WRITE
is a synonym for OPTIMISTIC_FORCE_INCREMENT
. They exist for historical reasons and in my opinion should be marked as @Deprecated
. The historical reason in the case is because they are bequeathed from JPA 1, which only had manners READ
and WRITE
. As from JPA 2, the part of Locking was revised and reworked, and the other modes were created, making these two existing modes obsolete.
The way NONE
is what disables any Locking and let anything happen that happens. This is the default mode for entities that does not contain any field annotated with @Version
.
The way OPTIMISTIC
is what uses the lock optimistic, but this only works when there is a field @Version
. Otherwise, it behaves like NONE
. When applied to versioned entities, it allows this to be read by other threads, but not altered or deleted. In the event of competing changes or exclusions, a OptimisticLockException
is released.
The way OPTIMISTIC_FORCE_INCREMENT
is similar to OPTIMISTIC
, but it forces the version to increase. As a consequence, it causes the entity to be modified, so that if there are two threads accessing the same entity in this way, the last one to do the commit will have a OptimisticLockException
.
Optimistic modes do not use the mechanism of lock and instead, they do the lock in the application. Already the pessimistic modes delegate the lock to the SGBD.
The way PESSIMISTIC_READ
locks tuples in the database for change and deletion, but still allows concurrent readings.
The way PESSIMISTIC_WRITE
locks tuples in the database for change, deletion and concurrent readings.
The way PESSIMISTIC_FORCE_INCREMENT
is the combination of PESSIMISTIC_WRITE
with the OPTIMISTIC_FORCE_INCREMENT
. It’s for when you want to use the lock optimistic and pessimistic at the same time or for when you do lock pessimistic in changing versioned entities.
If a lock pessimistic cannot be obtained from the database, a PessimisticLockException
is launched.
If the preview JPA needs or wants, it can promote a lock OPTIMISTIC
for OPTIMISTIC_FORCE_INCREMENT
or a PESSIMISTIC_READ
for PESSIMISTIC_WRITE
. In particular, it will do so if the entity in question undergoes change or exclusion. It is possible to obtain OptimisticLockException
or PessimisticLockException
if such promotion is not possible.
Hibernate also has two modes of lock optimist who are not standard of JPA which is the ALL
, whether any field of the entity has undergone any concurrent change and the DIRTY
verifying whether any of the entity’s modified fields have undergone a concurrent change, but allowing concurrent changes to the other fields.
The pessimistic way has a timeout which can be specified with the property javax.persistence.lock.timeout
. It can be specified in the methods of EntityManager
which contains a list of properties together with the LockModeType
. These methods are, namely: lock
; find
and refresh
. The method setProperty
can also be used. It can also be specified in persistence.xml
, in the annotation @NamedQuery
or when the EntityManagerFactory
. When this property has the value 0, it means that we will try to acquire the lock pessimistic immediately and if this is not possible, a LockTimeoutException
is immediately launched. If the value is different, the preview JPA waits to try to acquire the lock again before launching a LockTimeoutException
. This value is in milliseconds. However this property is only one hint, therefore the preview JPA may choose to disobey her if she so chooses.
More information:
Browser other questions tagged java hibernate jpa
You are not signed in. Login or sign up in order to post.
I don’t know about java and Hibernate, but competitive to save data, either you are doing something wrong in the code (time of the Insert/ update) or solve with transaction isolation
– Rovann Linhalis