Class ProxyConnection

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

public class ProxyConnection extends JdbcInterceptor
The bottom-most interceptor, wrapping a PooledConnection. It intercepts Connection.close(), Connection.abort(java.util.concurrent.Executor), Object.toString(), PooledConnection.getConnection(), Object.equals(Object) and Object.hashCode(). Method names are compared with String.equals(Object) unless PoolConfiguration.setUseEquals(boolean) selects reference comparison.

The connection handle implements PooledConnection (and XAConnection for an XA pool). The pool manages session reuse itself, so the four listener methods are delegated to the driver's XA connection where one exists, and otherwise fail with an SQLException naming the method rather than accepting a notification the pool could never deliver faithfully.

  • Field Details

    • connection

      protected volatile PooledConnection connection
      The underlying pooled connection. Volatile because writes that end or re-arm a borrow have no synchronization on the reader's side.
    • borrowHandle

      protected volatile Object borrowHandle
      The connection handle the current borrow was served under, or null once the borrow has ended. It is the per-borrow identity that distinguishes a call of the current borrow from a late call of an earlier one.
    • pool

      protected volatile ConnectionPool pool
      The parent connection pool. Volatile because the close and abort branches read it without synchronization; reset writes the session before the pool so a reader never sees a null pool with a live session behind it.
  • Constructor Details

    • ProxyConnection

      protected ProxyConnection(ConnectionPool parent, PooledConnection con, boolean useEquals)
      Creates a new ProxyConnection wrapping the given pooled connection.
      Parameters:
      parent - the parent connection pool
      con - the pooled connection
      useEquals - whether to compare method names with String.equals(Object) rather than by reference
  • Method Details

    • getConnection

      public PooledConnection getConnection()
      Returns the underlying pooled connection.
      Returns:
      the pooled connection
    • setConnection

      public void setConnection(PooledConnection connection)
      Sets the underlying pooled connection.
      Parameters:
      connection - the pooled connection
    • getBorrowHandle

      public Object getBorrowHandle()
      Returns the handle of the borrow this interceptor is armed for.
      Returns:
      the current borrow's handle, or null once that borrow has ended - its own close or abort, or a teardown reset - until the recording of the next borrow's handle
    • setBorrowHandle

      public void setBorrowHandle(Object borrowHandle)
      Records the handle of the borrow this interceptor serves. Only ConnectionPool.setupConnection(PooledConnection) calls this, with the handle it is about to hand to the borrower.
      Parameters:
      borrowHandle - the new borrow's handle
    • getPool

      public ConnectionPool getPool()
      Returns the parent connection pool.
      Returns:
      the connection pool
    • setPool

      public void setPool(ConnectionPool pool)
      Sets the parent connection pool.
      Parameters:
      pool - the connection pool
    • 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
    • isWrapperFor

      public boolean isWrapperFor(Class<?> iface)
      Checks whether this interceptor wraps the given interface. This is the view from the interceptor itself; the contract of the connection handle the pool hands out - which also implements Connection and PooledConnection (and XAConnection on XA pools) - is answered by the dispatch in invoke(Object, Method, Object[]).
      Parameters:
      iface - the interface to check
      Returns:
      true if this interceptor wraps the given interface
    • unwrap

      public Object unwrap(Class<?> iface) throws SQLException
      Unwraps the connection to the given interface.
      Parameters:
      iface - the interface to unwrap to
      Returns:
      the unwrapped connection. The pool-internal PooledConnection type is not exposed through the public Wrapper contract.
      Throws:
      SQLException - if the connection does not wrap the given interface
    • 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
    • isClosed

      public boolean isClosed()
      Returns true if the underlying connection has been closed or discarded.
      Returns:
      true if closed or discarded
    • getDelegateConnection

      public PooledConnection getDelegateConnection()
      Returns the delegate pooled connection.
      Returns:
      the delegate pooled connection
    • getParentPool

      public ConnectionPool getParentPool()
      Returns the parent connection pool.
      Returns:
      the parent connection pool
    • toString

      public String toString()
      Overrides:
      toString in class Object