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.