Hi everybody,
I have the following situation, and I would like to check if there is any 'best-practice' or workaround for it.
I have an Entity, which has @Version property setted, in 95% of the cases, the optimistic locking is fine.
For one process, which has high concurrency (is only executed 1 hour at night), I need to make a pessimistic lock on this entity.
What I do is:
MyEntity o = em.find(MyEntity.class, myKey);
em.lock(o, LockModeType.READ);
....
The problem that we have is that the lock sentence throw an OptimisticLockException.
I think that between we read the entity and we lock them, other threads are modifying it.
Is it right to get that exception ?
Is it possible to read the entity using JPA locking it in the first read ?
Is it possible to have an entity which use optimistic lock in some situations and pessimistic lock in others ?
Thanks in advance
Best Regards
Atuin
Hibernate version: 3.2.0.cr2
Full stack trace of any exception that occurs:
Hibernate:
select
SEA_ID
from
CRP_ACT_SESSION_EN_CURSO
where
SEA_ID =?
and SGUTIMESTAMP =? for update
[ACTIVE] ExecuteThread: '6' for queue: 'weblogic.kernel.Default (self-tuning)' -
--> 16:33:35,322. DEBUG AbstractBatcher:476 - preparing statement
[ACTIVE] ExecuteThread: '6' for queue: 'weblogic.kernel.Default (self-tuning)' -
--> 16:33:35,322. DEBUG LongType:80 - binding '302' to parameter: 1
[ACTIVE] ExecuteThread: '6' for queue: 'weblogic.kernel.Default (self-tuning)' -
--> 16:33:35,322. DEBUG LongType:80 - binding '5' to parameter: 2
[ACTIVE] ExecuteThread: '6' for queue: 'weblogic.kernel.Default (self-tuning)' -
--> 16:33:35,338. DEBUG AbstractBatcher:366 - about to close PreparedStatement (
open PreparedStatements: 1, globally: 1)
[ACTIVE] ExecuteThread: '6' for queue: 'weblogic.kernel.Default (self-tuning)' -
--> 16:33:35,338. DEBUG AbstractBatcher:525 - closing statement
[ACTIVE] ExecuteThread: '6' for queue: 'weblogic.kernel.Default (self-tuning)' -
--> 16:33:35,338. DEBUG ConnectionManager:398 - aggressively releasing JDBC conn
ection
[ACTIVE] ExecuteThread: '6' for queue: 'weblogic.kernel.Default (self-tuning)' -
--> 16:33:35,338. DEBUG ConnectionManager:435 - releasing JDBC connection [ (ope
n PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
[ACTIVE] ExecuteThread: '6' for queue: 'weblogic.kernel.Default (self-tuning)' -
--> 16:33:35,338. ERROR CrpActualizadorAppl:91 - Exception de updateSession = or
g.hibernate.StaleObjectStateException: Row was updated or deleted by another tra
nsaction (or unsaved-value mapping was incorrect): [crm.appl.crp.actualizador.do
main.CrpSessionActualizadorDO#302]
javax.persistence.OptimisticLockException: org.hibernate.StaleObjectStateExcepti
on: Row was updated or deleted by another transaction (or unsaved-value mapping
was incorrect): [crm.appl.crp.actualizador.domain.CrpSessionActualizadorDO#302]
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException
(AbstractEntityManagerImpl.java:551)
at org.hibernate.ejb.AbstractEntityManagerImpl.lock(AbstractEntityManage
rImpl.java:340)
at crm.core.persistence.FwkAuditorEntityManager.lock(FwkAuditorEntityMan
ager.java:172)
at crm.appl.crp.actualizador.appl.CrpActualizadorAppl.updateSession(CrpA
ctualizadorAppl.java:120)
at crm.appl.crp.actualizador.appl.CrpActualizadorEjbSn.updateSession(Crp
ActualizadorEjbSn.java:82)
at crm.appl.crp.actualizador.appl.CrpActualizadorEjbSn_au1gi7_EOImpl.upd
ateSession(CrpActualizadorEjbSn_au1gi7_EOImpl.java:279)
at crm.appl.crp.actualizador.appl.CrpActualizadorRmBDlg.updateSession(Cr
pActualizadorRmBDlg.java:99)
at crm.appl.crp.actualizador.appl.CrpActualizadorAppl.process(CrpActuali
zadorAppl.java:177)
at crm.appl.crp.actualizador.appl.CrpActualizadorEjbSn.process(CrpActual
izadorEjbSn.java:152)
at crm.appl.crp.actualizador.appl.CrpActualizadorEjbSn_au1gi7_EOImpl.pro
cess(CrpActualizadorEjbSn_au1gi7_EOImpl.java:207)
at crm.appl.crp.actualizador.appl.CrpActualizadorEjbSn_au1gi7_EOImpl_WLS
kel.invoke(Unknown Source)
at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:517)
at weblogic.rmi.cluster.ClusterableServerRef.invoke(ClusterableServerRef
.java:224)
at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:407)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(Authenticate
dSubject.java:363)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:
147)
at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.jav
a:403)
at weblogic.rmi.internal.BasicServerRef.access$300(BasicServerRef.java:5
6)
at weblogic.rmi.internal.BasicServerRef$BasicExecuteRequest.run(BasicSer
verRef.java:934)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:181)
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted b
y another transaction (or unsaved-value mapping was incorrect): [crm.appl.crp.ac
tualizador.domain.CrpSessionActualizadorDO#302]
at org.hibernate.dialect.lock.SelectLockingStrategy.lock(SelectLockingSt
rategy.java:78)
at org.hibernate.persister.entity.AbstractEntityPersister.lock(AbstractE
ntityPersister.java:1282)
at org.hibernate.event.def.AbstractLockUpgradeEventListener.upgradeLock(
AbstractLockUpgradeEventListener.java:88)
at org.hibernate.event.def.DefaultLockEventListener.onLock(DefaultLockEv
entListener.java:64)
at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:586)
at org.hibernate.impl.SessionImpl.lock(SessionImpl.java:578)
at org.hibernate.ejb.AbstractEntityManagerImpl.lock(AbstractEntityManage
rImpl.java:337)
... 19 more
Name and version of the database you are using: Oracle 10g
Debug level Hibernate log excerpt: DEBUG
|