Class StatementFinalizer

All Implemented Interfaces:
InvocationHandler

public class StatementFinalizer extends AbstractCreateStatementInterceptor
Keeps track of statements associated with a connection and invokes close upon Connection.close() Useful for applications that don't close the associated statements after being done with a connection.

A statement is tracked with a strong reference until it is closed: an application that forgot about a statement is exactly the case the interceptor exists for, so finalisation must not depend on that statement still being reachable when the connection is returned. A statement closed through the handle this interceptor returns is forgotten at that moment, which keeps the tracked list bounded by the statements that are genuinely still open.

A close that reaches the statement by another route cannot be observed by that removal, so its entry is reclaimed at the connection return: there the renewed close is a no-op on a statement the application had already closed, and the close it still owed on one it had not. That assumes the swallowed close did not itself recycle the statement into a cache: a recycling interceptor below this one would have parked it open, and the return-time close would then close a statement a live cache entry still holds. StatementCache is the module's recycling interceptor and refuses to park while it sits below this finalizer, so the ordering is safe for it; a third-party recycling interceptor is not covered by that guarantee. A creation still in flight while the connection is returned is the one case that return cannot reach - it registers after the return drained the list - and is closed where it arrives instead of being tracked.

Tracked statements are normally handed to the application as proxies implementing the standard JDBC statement interfaces, as is the statement facade the pool always installs in front of this interceptor and as are the proxies of the other statement-wrapping interceptors; the driver's own statement class is then not reachable by casting. If the tracking proxy cannot be created, the raw driver statement is returned instead and the statement stays tracked until the connection is returned. The Wrapper methods are delegated to the driver, and unwrap is the supported way to reach driver-specific statement methods. A statement the application reaches that way is still tracked here and is closed, like any other tracked statement, when the connection is returned - unless an interceptor listed after this one recycles the statement instead of closing it, as a statement cache beneath this interceptor does.

Tracking covers the statements created through the pooled connection handle. A statement created on the driver's own connection - the object Connection.unwrap(Connection.class) hands back - never reaches this interceptor and is neither tracked nor closed when the connection is returned.

  • Field Details

  • Constructor Details

    • StatementFinalizer

      public StatementFinalizer()
      Default constructor.
  • Method Details

    • createStatement

      public Object createStatement(Object proxy, Method method, Object[] args, Object statement, long time)
      Description copied from class: AbstractCreateStatementInterceptor
      This method will be invoked after a successful statement creation. This method can choose to return a wrapper around the statement or return the statement itself. If this method returns a wrapper then it should return a wrapper object that implements one of the following interfaces. Statement, PreparedStatement or CallableStatement

      An implementation must not make the statement reachable from any other code before it returns, because if this method throws then the statement is closed on a best-effort basis by the interceptor base class before the throwable is propagated to the application.

      Specified by:
      createStatement in class AbstractCreateStatementInterceptor
      Parameters:
      proxy - the actual proxy object
      method - the method that was called. It will be one of the methods defined in AbstractCreateStatementInterceptor.STATEMENT_TYPES
      args - the arguments to the method
      statement - the statement that the underlying connection created
      time - elapsed time in milliseconds, measured with the monotonic clock
      Returns:
      a Statement object
    • closeInvoked

      public void closeInvoked()
      Description copied from class: AbstractCreateStatementInterceptor
      Method invoked when the operation Connection.close() is invoked. It runs before the close is passed down the chain, so that a hook can still reach the connection while it is alive - statements must be closed before the session is handed to the next borrower. Implementation of this method should be thought through with care, as no actions should trigger an exception. An interceptor that nevertheless throws is isolated: the exception is logged and ignored, the remaining interceptors in the chain still receive the close, and the connection is returned to the pool as it would have been. The fatal virtual machine errors the pool never swallows are the exception: those propagate.
      Specified by:
      closeInvoked in class AbstractCreateStatementInterceptor
    • setProperties

      public void setProperties(Map<String, PoolProperties.InterceptorProperty> properties)
      Description copied from class: JdbcInterceptor
      Called during the creation of an interceptor, once per instance: once for each instance created to build a pooled connection's interceptor chain, and once on the throwaway instance of each configured class that receives JdbcInterceptor.poolStarted(ConnectionPool) at pool start and JdbcInterceptor.poolClosed(ConnectionPool) at pool close. The pool passes the live map of the interceptor definition, shared across all these instances, so it must be treated as read-only (see JdbcInterceptor.getProperties()). Override this method to perform type casts between string values and object properties.
      Overrides:
      setProperties in class JdbcInterceptor
      Parameters:
      properties - The properties
    • reset

      public void reset(ConnectionPool parent, PooledConnection con)
      Description copied from class: AbstractCreateStatementInterceptor
      no-op for this interceptor. no state is stored.
      Overrides:
      reset in class AbstractCreateStatementInterceptor
      Parameters:
      parent - - the connection pool owning the connection
      con - - the pooled connection