Hi,
I have discovered a race condition between
EntityInstanceInterceptor (EII) and the EntityInstanceCache.(EIC)
I think the same problem exists for StatefulSessionBeans.
The sequence goes something like:
The EntityLockInterceptor creates a lock with the
key and transaction from the invocation.
<race>
EII does Cache.get() which returns an Enterprise Context
EIC.canPassivate decides it should passivate the context
(It is not locked and there is no transaction yet)
EIC passivates, removing the id and key when the context goes
back in the pool.
EII populates the context with the transaction, principal, etc
and places it in the invocation.
</race>
The EntitySynchronizationInterceptor receives a Context with
a null cache key, which it uses to retrieve the lock. But a lock
with a null key.
It doesn't discover the mistake until it checks ctx.isValid(),
where it trys to load the entity and fails.
To recover from this, it tries to invoke
lock.wontSynchronize(), but again it is with the "null" lock.
The transaction is not removed from the original lock.
Only when it returns to the EntityLockInterceptor and
does removeLockRef() with the original key from the invocation
is the error discovered.
java.lang.IllegalStateException: removing bean lock and
it has tx set!
at
org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock.r
emoveRef(QueuedPessimisticEJBLock.java:469)
at org.jboss.ejb.BeanLockManager.removeLockRef
(BeanLockManager.java:78)
at org.jboss.ejb.plugins.EntityLockInterceptor.invoke
(EntityLockInterceptor.java:124)
I've only reproduced this with a very small cache.
In fact a maximum cache size of 1 :-)
One fix is asking the BeanLockManager if there are any locks before
passivating. Is this the correct fix? It passes the testsuite. Bill?
I'll try to write a testcase, but since it is a race
condition, it might not always be reproducable.
Possible: a custom EntityInstanceInterceptor with a sleep().
This also leads to a deadlock. Because the original lock is never
released, nothing else can access the entity.
at java.lang.Object.wait(Native Method)
- waiting on <040E8E78> (a
org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock$TxLock)
at
org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock.waitForTx(QueuedPessimisticEJBLock.java:274)
- locked <040E8E78> (a
org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock$TxLock)
at
org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock.doSchedule(QueuedPessimisticEJBLock.java:192)
at
org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock.schedule(QueuedPessimisticEJBLock.java:139)
at
org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:103)
at
org.jboss.ejb.plugins.EntityCreationInterceptor.invoke(EntityCreationInterceptor.java:69)
at
org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:108)
at
org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:184)
at
org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:66)
at
org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:130)
at
org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:205)
at
org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:154)
at org.jboss.ejb.EntityContainer.invoke(EntityContainer.java:481)
at
org.jboss.ejb.plugins.local.BaseLocalProxyFactory.invoke(BaseLocalProxyFactory.java:351)
at
org.jboss.ejb.plugins.local.EntityProxy.invoke(EntityProxy.java:38)
at $Proxy50.getName(Unknown Source)
Regards,
Adrian
_________________________________________________________________
Chat with friends online, try MSN Messenger: http://messenger.msn.com
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development