Class StatementCache
- All Implemented Interfaces:
InvocationHandler, StatementCacheMBean
PreparedStatement and/or CallableStatement instances on a connection.
A cache hit is answered by this interceptor alone: the rest of the chain is not invoked for it, and a recycled
statement is reset to driver defaults. Interceptors listed after this one therefore do not see reused statements, so
QueryTimeoutInterceptor and StatementFinalizer must be listed before the cache. A tracker such as
StatementFinalizer beneath the cache would close a parked statement at connection return, so the cache then
refuses to park at all.
With JMX enabled, a cache publishes an MBean below its connection's MBean. It is released when the connection goes
out of service (the chain teardown reset(null, null)), when the pool closes, or when the pool MBean is
deregistered - not on an ordinary return and re-borrow. A pool abandoned without closing keeps its registrations,
and through them the pool, its sessions and its driver class loader reachable.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected classProxy for a cached prepared statement.Nested classes/interfaces inherited from class StatementDecoratorInterceptor
StatementDecoratorInterceptor.ResultSetProxy, StatementDecoratorInterceptor.StatementProxy<T> -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected static final String[]All statement types (prepared and callable).protected static final String[]Callable statement type only.protected static final String[]No statement types.protected static final String[]Prepared statement type only.protected static final StringAttribute key for storing the statement cache in connection attributes.Fields inherited from class StatementDecoratorInterceptor
RESULTSET_TYPES, resultSetConstructorFields inherited from class AbstractCreateStatementInterceptor
CREATE_STATEMENT, CREATE_STATEMENT_IDX, EXECUTE, EXECUTE_BATCH, EXECUTE_LARGE_BATCH, EXECUTE_LARGE_UPDATE, EXECUTE_QUERY, EXECUTE_TYPES, EXECUTE_UPDATE, GET_GENERATED_KEYS, GET_RESULTSET, GET_STATEMENT, PREPARE_CALL, PREPARE_CALL_IDX, PREPARE_STATEMENT, PREPARE_STATEMENT_IDX, RESULTSET_IDX, STATEMENT_TYPE_COUNT, STATEMENT_TYPESFields inherited from class JdbcInterceptor
ABORT_VAL, CLOSE_VAL, EQUALS_VAL, GETCONNECTION_VAL, HASHCODE_VAL, ISCLOSED_VAL, ISVALID_VAL, ISWRAPPERFOR_VAL, properties, TOSTRING_VAL, UNWRAP_VAL -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionbooleanCaches the given statement proxy if there is room in the cache.voidCloses the given cached statement by forcing it to close.protected org.apache.tomcat.jdbc.pool.interceptor.StatementCache.CacheKeycreateCacheKey(Method method, Object[] args) Creates a cache key from the given method and arguments.protected org.apache.tomcat.jdbc.pool.interceptor.StatementCache.CacheKeycreateCacheKey(String methodName, Object[] args) Creates a cache key from the given method name and arguments.protected ObjectcreateDecorator(Object proxy, Method method, Object[] args, Object statement, Constructor<?> constructor, String sql) Creates a proxy for a Statement.voiddisconnected(ConnectionPool parent, PooledConnection con, boolean finalizing) Called whenConnection.close()is called on the underlying connection.protected ConcurrentHashMap<org.apache.tomcat.jdbc.pool.interceptor.StatementCache.CacheKey, StatementCache.CachedStatement> getCache()Returns the statement cache for the current pooled connection.intThe pool-wide count of statements parked in the caches of all connections.intReturns the cache size for the current connection: the statements parked in this connection's cache.intReturns the maximum size of the statement cache.String[]getTypes()Returns the statement types being cached.Gets invoked each time an operation onConnectionis invoked.booleanChecks if callable statements are being cached.Checks if a statement for the given method and arguments is currently cached.booleanChecks if prepared statements are being cached.voidpoolClosed(ConnectionPool pool) This method is invoked by a connection pool when the pool is closed.voidpoolStarted(ConnectionPool pool) This method is invoked by a connection pool when the pool is first started up, usually when the first connection is requested.booleanRemoves the given statement from the cache.voidreset(ConnectionPool parent, PooledConnection con) no-op for this interceptor. no state is stored.voidsetProperties(Map<String, PoolProperties.InterceptorProperty> properties) 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 receivesJdbcInterceptor.poolStarted(ConnectionPool)at pool start andJdbcInterceptor.poolClosed(ConnectionPool)at pool close.voidReleases any MBean this interceptor published for the connection it serves, without tearing down the connection state.Methods inherited from class StatementDecoratorInterceptor
closeInvoked, createStatement, getResultSetConstructor, isResultSetMethods inherited from class AbstractCreateStatementInterceptor
elapsedMillis, getConstructor, isExecute, isStatement, processMethods inherited from class JdbcInterceptor
compare, compare, getNext, getProperties, isUseEquals, setNext, setUseEquals
-
Field Details
-
ALL_TYPES
All statement types (prepared and callable). -
CALLABLE_TYPE
Callable statement type only. -
PREPARED_TYPE
Prepared statement type only. -
NO_TYPE
No statement types. -
STATEMENT_CACHE_ATTR
Attribute key for storing the statement cache in connection attributes.
-
-
Constructor Details
-
StatementCache
public StatementCache()Default constructor.
-
-
Method Details
-
isCachePrepared
public boolean isCachePrepared()Description copied from interface:StatementCacheMBeanChecks if prepared statements are being cached.- Specified by:
isCachePreparedin interfaceStatementCacheMBean- Returns:
- true if prepared statement caching is enabled
-
isCacheCallable
public boolean isCacheCallable()Description copied from interface:StatementCacheMBeanChecks if callable statements are being cached.- Specified by:
isCacheCallablein interfaceStatementCacheMBean- Returns:
- true if callable statement caching is enabled
-
getMaxCacheSize
public int getMaxCacheSize()Description copied from interface:StatementCacheMBeanReturns the maximum size of the statement cache.- Specified by:
getMaxCacheSizein interfaceStatementCacheMBean- Returns:
- maximum cache size
-
getTypes
Returns the statement types being cached.A copy is returned because the arrays a cache matches against are shared by every instance in the class loader; mutating the array behind the accessor would change what every pool in the JVM caches, not just this one. This is an extension accessor: the pool itself does not read it.
- Returns:
- array of statement type strings
-
getCacheSize
public int getCacheSize()The pool-wide count of statements parked in the caches of all connections. Parked statements are physically open until the cache is disposed, so this is not the number of statements ready to run.- Specified by:
getCacheSizein interfaceStatementCacheMBean- Returns:
- the count, or
-1once this interceptor has been disposed and the pool-wide counter is gone
-
setProperties
Description copied from class:JdbcInterceptorCalled 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 receivesJdbcInterceptor.poolStarted(ConnectionPool)at pool start andJdbcInterceptor.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 (seeJdbcInterceptor.getProperties()). Override this method to perform type casts between string values and object properties.- Overrides:
setPropertiesin classJdbcInterceptor- Parameters:
properties- The properties
-
poolStarted
Description copied from class:JdbcInterceptorThis method is invoked by a connection pool when the pool is first started up, usually when the first connection is requested. Interceptor classes can override this method if they keep static variables or other tracking means around. This method is only invoked on a single instance of the interceptor, and not on every instance created. That instance is a throwaway created solely for this notification: it shares no state with the instances in any connection's chain or with the instance that later receivesJdbcInterceptor.poolClosed(ConnectionPool), so any state this hook needs must be static or keyed on the pool. An exception thrown here aborts pool initialization: the pool is closed and the failure is reported to the caller that triggered the start-up.- Overrides:
poolStartedin classJdbcInterceptor- Parameters:
pool- - the pool that is being started up.
-
poolClosed
Description copied from class:JdbcInterceptorThis method is invoked by a connection pool when the pool is closed. Interceptor classes can override this method if they keep static variables or other tracking means around. This method is only invoked on a single instance of the interceptor, and not on every instance created. That instance is a throwaway created solely for this notification: it shares no state with the instances in any connection's chain, so any state this hook needs must be static or keyed on the pool. The callback is delivered for every definition the pool told about itsstart, whatever the interceptor configuration lists by the time the pool closes, and additionally for any definition the configuration has gained since the start. An override that registers state at the start must therefore find its release delivered even after its definition has been removed from a live pool's configuration, and must tolerate a delivery it did not pair with its own start. An exception thrown here is logged at debug level and otherwise ignored; the pool close continues.- Overrides:
poolClosedin classJdbcInterceptor- Parameters:
pool- - the pool that is being closed.
-
reset
Description copied from class:AbstractCreateStatementInterceptorno-op for this interceptor. no state is stored.- Overrides:
resetin classAbstractCreateStatementInterceptor- Parameters:
parent- - the connection pool owning the connectioncon- - the pooled connection
-
unregisterMBean
public void unregisterMBean()Description copied from class:JdbcInterceptorReleases any MBean this interceptor published for the connection it serves, without tearing down the connection state. The pool calls this when it releases its own MBean while the pool stays live; the connection and its chain remain usable, and a later borrow can publish the interceptor again. The default does nothing; an interceptor that publishes an MBean overrides it.- Overrides:
unregisterMBeanin classJdbcInterceptor
-
disconnected
Description copied from class:JdbcInterceptorCalled whenConnection.close()is called on the underlying connection. This is to notify the interceptors, that the physical connection has been released. 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 are still notified, and the physical connection is closed as it would have been. As forJdbcInterceptor.reset(ConnectionPool, PooledConnection), a hook must not rewire the chain from this callback: chain topology is owned by the pool.- Overrides:
disconnectedin classJdbcInterceptor- Parameters:
parent- - the connection pool that this connection belongs tocon- - the pooled connection that holds this connectionfinalizing- - if this connection is finalizing. True means that the pooled connection will not reconnect the underlying connection
-
closeStatement
Closes the given cached statement by forcing it to close.- Parameters:
st- the cached statement to close
-
createDecorator
protected Object createDecorator(Object proxy, Method method, Object[] args, Object statement, Constructor<?> constructor, String sql) throws InstantiationException, IllegalAccessException, InvocationTargetException Description copied from class:StatementDecoratorInterceptorCreates a proxy for a Statement.- Overrides:
createDecoratorin classStatementDecoratorInterceptor- Parameters:
proxy- The proxy object on which the method that triggered the creation of the statement was called.method- The method that was called on the proxyargs- The arguments passed as part of the method call to the proxystatement- The statement object that is to be proxiedconstructor- The constructor for the desired proxysql- The sql of the statement- Returns:
- A new proxy for the Statement
- Throws:
InstantiationException- Couldn't instantiate objectIllegalAccessException- Inaccessible constructorInvocationTargetException- Exception thrown from constructor
-
invoke
Description copied from class:JdbcInterceptorGets invoked each time an operation onConnectionis invoked.The base implementation passes the call to the
nextinterceptor in the chain. When there is no next interceptor, the call fails fast with aNullPointerException: a chain built by the pool always ends in theProxyConnectionterminal, so reaching this case means a chain was hand-built without a terminal link. Interceptors that do not answer a call themselves continue it withsuper.invoke(proxy, method, args).- Specified by:
invokein interfaceInvocationHandler- Overrides:
invokein classAbstractCreateStatementInterceptor- Throws:
Throwable
-
isCached
Checks if a statement for the given method and arguments is currently cached.- Parameters:
method- the SQL method (prepareStatement or prepareCall)args- the method arguments- Returns:
- the cached statement, or null if not cached
-
cacheStatement
Caches the given statement proxy if there is room in the cache.The insertion is atomic: of two statements closed concurrently under one key exactly one is parked, and the other is refused as a duplicate - a park can never overwrite, and so can never orphan, a statement another close has already parked. A proxy that is refused was never in the map, and the caller that receives
falsemust close the statement it offered.- Parameters:
proxy- the statement proxy to cache- Returns:
- true if the statement was cached, false otherwise
-
removeStatement
Removes the given statement from the cache. The removal is identity-aware: it only takes effect while the entry under the statement's key still holds this very proxy, so a proxy that was never parked - or is no longer the cached statement - cannot evict a different statement parked under an equal key.- Parameters:
proxy- the statement proxy to remove- Returns:
- true if the statement was removed, false otherwise
-
getCache
protected ConcurrentHashMap<org.apache.tomcat.jdbc.pool.interceptor.StatementCache.CacheKey, StatementCache.CachedStatement> getCache()Returns the statement cache for the current pooled connection.- Returns:
- the cache map, or null if the connection has been closed
-
getCacheSizePerConnection
public int getCacheSizePerConnection()Description copied from interface:StatementCacheMBeanReturns the cache size for the current connection: the statements parked in this connection's cache. Parked statements are physically open until the cache is disposed, so this is not the number of statements ready to run. A read against an interceptor that is not bound to a pooled connection, for instance one made while a disposal is in progress, is answered quietly rather than logged.- Specified by:
getCacheSizePerConnectionin interfaceStatementCacheMBean- Returns:
- number of cached statements for this connection, or
0if this interceptor instance is not bound to a pooled connection
-
createCacheKey
-
createCacheKey
protected org.apache.tomcat.jdbc.pool.interceptor.StatementCache.CacheKey createCacheKey(String methodName, Object[] args) Creates a cache key from the given method name and arguments.- Parameters:
methodName- the SQL method nameargs- the method arguments- Returns:
- the cache key, or null if the method name doesn't match a cached type
-