You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by bu...@apache.org on 2022/03/03 22:33:18 UTC

[Bug 65929] New: Connection is not released on Connection.abort() call

https://bz.apache.org/bugzilla/show_bug.cgi?id=65929

            Bug ID: 65929
           Summary: Connection is not released on Connection.abort() call
           Product: Tomcat Modules
           Version: unspecified
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: jdbc-pool
          Assignee: dev@tomcat.apache.org
          Reporter: okutishchev@apple.com
  Target Milestone: ---

[NOT A CONTRIBUTION]


JDBC Pool Version: 9.0.49
Database: Oracle
JDBC Version:  19.3.0.0
OS: Mac, Linux


The problem I'm running into:
We are using Tomcat JDBC Pool. When getting the network failure between server
and database something like 'Connection Reset by Peer' ORM framework we are
using  'abort' method from JDBC Connection which goes through the
ProxyConnection class. As a result underlying physical connection to DB is
closed but PooledConnection is not return to the pool.

The reason to using 'abort' is that oracle PhysicalConnection in case of
network failure sometimes goes to the inconsistent state and calling plain
'close' throws an unexpected exception.

Seems like ProxyConnection is missing special handling for the 'abort' method
which should call abort on the underlying connection and return PoolConnection
to the pool afterwards.

According to JDBC specification link -
https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#abort-java.util.concurrent.Executor-
calling 'abort' should perform close on the connection.

To reproduce following can be done:
Put a debug point to the code making a SQL query. Find in the call stack the
ProxyConnection class and make a call of abort on it. As a result underlying
connection is going to be closed by not return to the pool as released.

The easiest way to fix:
Put a handler for the 'abort' method which first abort the underlying
connection and when 'close' it with return to the pool. Same as 'close' is
handled.

As a workaround we have fixed that using interceptor:

[NOT A CONTRIBUTION]

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
   Object invoke = super.invoke(proxy, method, args);
   if (compare(ABORT_VAL, method) && findProxyConnectionInChain().isPresent())
{
       ProxyConnection proxyConnection = findProxyConnectionInChain().get();
       proxyConnection.getDelegateConnection().setDiscarded(true);
       try {
           super.invoke(proxy,
Connection.class.getDeclaredMethod(ProxyConnection.CLOSE_VAL), args);
       } catch (Exception e) {
                  // Error handling
       }

   }
   return invoke;
}

private Optional<ProxyConnection> findProxyConnectionInChain() {
   JdbcInterceptor next  = getNext();

   while (next != null) {
       if (next instanceof ProxyConnection) return 
Optional.of((ProxyConnection) next);
       next = next.getNext();
   }

   return Optional.empty();
}

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org