Semaphore in StatelessInstanceManager not released if 
EjbTransactionUtil.afterInvoke throws RuntimeException
------------------------------------------------------------------------------------------------------------

                 Key: OPENEJB-976
                 URL: https://issues.apache.org/jira/browse/OPENEJB-976
             Project: OpenEJB
          Issue Type: Bug
          Components: container system
    Affects Versions: 3.1
            Reporter: Tor-Einar Jarnbjo


When invoking an SLSB, a bean instance is retrieved from the 
StatelessInstanceManager in StatelessContainer.invoke 
(instanceManager.getInstance(callContext), line 160). At this point, a 
semaphore is aquired to limit the number of simultaneous calls to a specific 
SLSB type. Later, with a call to poolInstance in line 170, the semaphore is 
supposed to be released. In between, in line 169, the actual bean method is 
invoked within the StatelessContainer._invoke method. Here, in a finally-block, 
EjbTransactionUtil.afterInvoke is called to commit the transaction. If 
txPolicy.commit() (EjbTransactionUtil.java:74) throws a RuntimeException, the 
exception is never caught, StatelessInstanceManager.invoke will never reach 
line 170 and the semaphore is not released. After aquiring the semaphore 
"limit" times (whatever the semaphore limit is configured to) and running into 
problems in the commit phase, all further calls to the SLSB will block, because 
the semaphore cannot be aquired anymor
 e.

In our specific case, the DB commit fails because the backing Oracle DB is 
configured to not check for constraint violations until the transaction is 
commited. Eclipselink as JPA provider wraps the SQLException in a 
RuntimeException and causes the described problem:

Exception [EclipseLink-23011] (Eclipse Persistence Services - 1.0.2 (Build 
20081024)): org.eclipse.persistence.exceptions.TransactionException
Exception Description: UnitOfWork [UnitOfWork(
        ...
        at 
org.apache.geronimo.transaction.manager.TransactionManagerImpl.commit(TransactionManagerImpl.java:245)
        at 
org.apache.openejb.core.transaction.JtaTransactionPolicy.completeTransaction(JtaTransactionPolicy.java:291)
        at 
org.apache.openejb.core.transaction.TxRequiresNew.commit(TxRequiresNew.java:68)
        at 
org.apache.openejb.core.transaction.EjbTransactionUtil.afterInvoke(EjbTransactionUtil.java:74)
        at 
org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:231)
        at 
org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:169)
        ...

After going over the code, the same problem seem to be the case if the SLSB 
method itself throws a RuntimeException or an Error. In the catch block in 
StatelessContainer, lines 213-228, the RuntimeException/Error is categorized as 
a system exception (ExceptionType.SYSTEM), which causes the SLSB instance on 
purpose not to be put back in the pool. It is of course ok to throw away the 
instance, but the semaphore must be released here as well.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to