Details
-
Bug
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
2.2.0
-
None
Description
We're experiencing a connection leak in a distributed transaction when the system is under heavy load. We're using commons-dbcp (latest version) + eclipselink and narayana to perform transaction coordination.
From time to time we can see a stacktrace reporting an abandoned connection. We are trying to figure out what's the root cause and we think that might be some issue in the commons dbcp (not sure) . More specifically, this parte of the code:
ManagedConnection#updateTransactionStatus
if (transactionContext != null) { if (transactionContext.isActive()) { if (transactionContext != transactionRegistry.getActiveTransactionContext()) { throw new SQLException("Connection can not be used while enlisted in another transaction"); } return; } // transaction should have been cleared up by TransactionContextListener, but in // rare cases another lister could have registered which uses the connection before // our listener is called. In that rare case, trigger the transaction complete call now transactionComplete(); }
If the transactionContext is different than null but the state is not "active" (ex: STATUS_ROLLEDBACK, STATUS_ROLLING_BACK, etc) it executes the transactionComplete mothod that clears the reference to a shared connection and after that the connection is never closed (returned to the pool).
If we move the transactionComplete(); to an else,(see below), the connection leak does not happen.
if (transactionContext != null) { if (transactionContext.isActive()) { if (transactionContext != transactionRegistry.getActiveTransactionContext()) { throw new SQLException("Connection can not be used while enlisted in another transaction"); } return; } } else { transactionComplete(); }
After this the dbcp unit tests still pass but I'm not sure about this changes. Can you please check?
Thanks
Attachments
Attachments
Issue Links
- relates to
-
DBCP-491 Ensure DBCP ConnectionListener can deal with transaction managers which invoke rollback in a separate thread
- Resolved