I have made a prototype of a client side statement cache. A description
of the changes made follows below, and I would like feedback on the
suggested approach. Note that this is a very early version, and there
are probably several things that haven't received the attention they
should. I also need to "forward" all calls in the logical prepared
statement before it can be used. Currently it only supports executeQuery
and close. There is also some JDBC 40 specific classes missing.
I also know there are some synchronization issues I have to work on,
in some places JavaDoc is missing and
DatabaseMetaData.supportsStatementPooling must return true for the
All changes are currently restricted to the client packages, and the
prefix 'org.apache.derby.client' is omitted for conciseness.
ClientPooledConnection: Added a statement cache and logic for
instantiating it if 'maxStatements' is bigger than zero. Also added
logic for creating either LogicalConnection (if no caching) or a
CachingLogicalConnection. If caching is disabled, things will be
exactly as before after a call to getConnection.
ClientJDBCObjectFactory: Extended the interface with methods for
creating a CachingLogicalCreation and a LogiclPreparedStatement
(both new classes).
CachingLogicalConnection: A new logical connection class that caches
prepared statement objects and creates logical prepared statements.
LogicalPreparedStatement/-40: Logical prepared statement with special
close logic. Physical prepared statement is added to the statement
cache on close if there is no other matching query already in there.
I'm wondering if we could put this in the shared package, or are we not
there yet on code sharing between the two drivers?
The cache is intended to hold only a single "instance" of each
statement, and all statements in the cache are free. If a statement is
in use, it will not be in use. Whether a statement goes into the cache
or not, is determined when LogicalPreparedStatement.close is called.
Added three things;
JDBCStatementCache: The cache itself. Holds PreparedStatement objects.
Statement keys: An interface for the keys (StatementKey) and 5
different keys. Only the interface is public, the implementations
are hidden inside the package. I'm sure there are other design
possibilities here. Must write equality tests and verify hash codes.
StatementKeyFactory: A factory generating the appropriate keys based
on the input information. Note that it recognizes default settings
for some properties and generates a simplified key in some cases.
Have modified two data source classes here. I'm not 100% sure about the
existing data source hierarchy, but making my things fit in there didn't
require many changes. Changed files:
ClientBaseDataSource: Added variable 'maxStatements' and a getter
method. This property doesn't make sense for a basic data source,
but this class is what is being passed around when data sources are
created. Another option is to cast the object, but that requires
ClientConnectionPoolDataSource: Added a setter for maximum number of
Added implementations of the factory methods for creating caching
connections and logical prepared statements, according to changes in the
interface (see interface am.ClientJDBCObjectFactory).
The caching work across multiple logical connections. Prepared
statements are not shared across physical connections.
Going forward I will incorporate suggestions and feedback from the
community, write tests and continue finishing the implementation.
I also plan to run the implementation in an application server
environment for some early-on testing. I'm also playing with the idea of
running suites.All with statement pooling, but I'm not sure how well
that will work...
When things are ready for proper review and commit, I will split the
changes into smaller parts and submit several more or less independent
Diff stats for prototype patch 'derby-3313-1a-early_prototype.diff':
client/ClientPooledConnection.java | 25 +
client/am/CachingLogicalConnection.java | 160 ++++++++++
client/am/ClientJDBCObjectFactory.java | 24 +
client/am/LogicalPreparedStatement.java | 393 ++++++++++++++++++++++++++
client/am/LogicalPreparedStatement40.java | 136 ++++++++
client/am/stmtcache/AutoGeneratedKeysKey.java | 51 +++
client/am/stmtcache/BasicKey.java | 65 ++++
client/am/stmtcache/ColumnIndexesKey.java | 69 ++++
client/am/stmtcache/ColumnNamesKey.java | 68 ++++
client/am/stmtcache/JDBCStatementCache.java | 137 +++++++++
client/am/stmtcache/QueryKey.java | 58 +++
client/am/stmtcache/StatementKey.java | 56 +++
client/am/stmtcache/StatementKeyFactory.java | 115 +++++++
client/net/ClientJDBCObjectFactoryImpl.java | 32 ++
client/net/ClientJDBCObjectFactoryImpl40.java | 32 ++
jdbc/ClientBaseDataSource.java | 22 +
jdbc/ClientConnectionPoolDataSource.java | 9
17 files changed, 1451 insertions, 1 deletion
All kinds of feedback are welcome