Class DisposableConnectionFacade

java.lang.Object
org.apache.tomcat.jdbc.pool.JdbcInterceptor
org.apache.tomcat.jdbc.pool.DisposableConnectionFacade
All Implemented Interfaces:
InvocationHandler

public class DisposableConnectionFacade extends JdbcInterceptor
A DisposableConnectionFacade object is the top most interceptor of the connection handle the pool hands out: the pool creates one per borrow, wrapping the per-borrow StatementFacade above the interceptor chain cached on the PooledConnection, which ends in the ProxyConnection over the physical session. Disposing the facade - breaking the link to that chain - is what makes a handle inert once its borrow has ended, so a handle kept past its borrow can never drive the session the pool has re-served to the next borrower.

The DisposableConnectionFacade intercepts seven method names. While the facade is live, the answers marked live are given; once it is disposed, the names marked disposed are answered by the facade itself and the call never reaches the chain:

  • Connection.close() - live: breaks the link between this facade and the next interceptor, then delegates the close to the chain, which returns the connection to the pool; may be called multiple times. Disposed: the no-op the JDBC specification prescribes for a closed connection.
  • Connection.abort(java.util.concurrent.Executor) - live: disposes of the facade in the same way, then delegates the abort to the chain, which ends the borrow. Disposed: the no-op the specification prescribes for a closed connection.
  • Object.equals(Object) and Object.hashCode() - answered in both states, with the identity of the handle: each borrow is one handle even over a physical session the pool has re-served.
  • Connection.isClosed() - live: delegated. Disposed: true.
  • Connection.isValid(int) - live: delegated. Disposed: false, the answer the JDBC contract gives a closed connection.
  • Object.toString() - live: delegated. Disposed: a custom string, so a released handle stays printable for logging.
Every other method on a disposed handle fails with an SQLException reporting the closed connection, the way a use of a closed connection fails; a live facade delegates it to the chain.

By default method names are compared with String.equals(Object); JdbcInterceptor.setUseEquals(boolean) called with a false argument switches an instance to reference comparison. This facade takes its value from the interceptor it wraps - in a configured pool, the top configured interceptor's own value, decided by that interceptor's useEquals property; the pool-level PoolConfiguration.setUseEquals(boolean) reaches the ProxyConnection at the bottom of the chain, not this class.

  • Constructor Details

    • DisposableConnectionFacade

      protected DisposableConnectionFacade(JdbcInterceptor interceptor)
      Construct a DisposableConnectionFacade that wraps the given interceptor.
      Parameters:
      interceptor - The next interceptor in the chain
  • Method Details

    • reset

      public void reset(ConnectionPool parent, PooledConnection con)
      Description copied from class: JdbcInterceptor
      Gets called each time the connection is borrowed from the pool This means that if an interceptor holds a reference to the connection the interceptor can be reused for another connection.
      This method may be called with null as both arguments when we are closing down the connection. When called for a shutdown reset, an interceptor that throws is isolated: the exception is logged and ignored, and the remaining interceptors in the chain are reset as well.
      Chain topology is owned by the pool: a hook must not call JdbcInterceptor.setNext(JdbcInterceptor) on itself or on any other link while the chain is wired, and in particular not from this callback. The walks that run this callback do not agree on when they read the next link - the walk at borrow time re-reads it after the callback, the shutdown walks read it before - so a hook that rewired its own link would be visited differently depending on which walk runs, and could be skipped or revisited without limit.
      Specified by:
      reset in class JdbcInterceptor
      Parameters:
      parent - - the connection pool owning the connection
      con - - the pooled connection
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • equals

      public boolean equals(Object obj)
      Overrides:
      equals in class Object
    • invoke

      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
      Description copied from class: JdbcInterceptor
      Gets invoked each time an operation on Connection is invoked.

      The base implementation passes the call to the next interceptor in the chain. When there is no next interceptor, the call fails fast with a NullPointerException: a chain built by the pool always ends in the ProxyConnection terminal, so reaching this case means a chain was hand-built without a terminal link. Interceptors that do not answer a call themselves continue it with super.invoke(proxy, method, args).

      Specified by:
      invoke in interface InvocationHandler
      Overrides:
      invoke in class JdbcInterceptor
      Throws:
      Throwable