-
Bug
-
Resolution: Unresolved
-
Major
-
JBossAS-3.2.7 Final, JBossAS-5.1.0.GA
-
None
-
None
Usecase:
All xx, xy, yy and xz are representing readonly entitybean-methods and are called on one EntityBean. CMT required and reentrant true.
The following methods are executed on the server in this order:
Thread1: calls entitybean.xx
Thread1: calls entitybean.xy
Thread2: calls entitybean.yy -> has to wait for the QueuedPessimisticEJBLock
Thread1: returns from entitybean.xy and frees the QueuedPessimisticEJBLock <--- BUG
Thread2: gets the QueuedPessimisticEJBLock but doesn't get the NonReentrantLock
Thread1: calls entitybean.xz -> has to wait for the QueuedPessimisticEJBLock and still holds the NonReentrantLock
Result: Undetected deadlock between QueuedPessimisticEJBLock and NonReentrantLock.
Please use the attached bug-0.1-SNAPSHOT.jar for verification. Main class for the test is locking.bug.DeadlockTest.
Our current workaround:
Created a subclass of QueuedPessimisticEJBLock and override problematic method "endInvocation":
public void endInvocation(Invocation P_mi)
{
Transaction F_tx = P_mi.getTransaction();
if (F_tx != null && F_tx.equals(getTransaction()))
{
EntityEnterpriseContext F_ctx = (EntityEnterpriseContext)P_mi.getEnterpriseContext();
if(F_ctx == null)
{ endTransaction(F_tx); } else if(F_ctx.hasTxSynchronization() == false)
{
NonReentrantLock F_mLock = F_ctx.getMethodLock();
if (F_mLock == null)
{ endTransaction(F_tx); } else
{
Object F_resourceHolder = F_mLock.getResourceHolder();
if (F_resourceHolder instanceof Thread
&& Thread.currentThread().equals(F_resourceHolder))
else if (F_resourceHolder instanceof Transaction
&& F_tx.equals(F_resourceHolder))
{ // don't end the transaction, because we still own the // lock! }
else
{ endTransaction(F_tx); } }
}
else
}
}