https://bz.apache.org/bugzilla/show_bug.cgi?id=70269
Bug ID: 70269
Summary: Regression: StatementCache no longer caches statements
when the driver's isPoolable() returns false
Product: Tomcat Modules
Version: unspecified
Hardware: All
OS: All
Status: NEW
Keywords: Regression
Severity: regression
Priority: P2
Component: jdbc-pool
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
Affects 11.0.26 onwards, 10.1.60 onwards, 9.0.122 onwards and main.
The fix for resetting statement properties between uses (bb64a055e2 on main,
56fe3e705d on 11.0.x, 006633d937 on 10.1.x, b5de155df8 on 9.0.x) made
CachedStatement.closeInvoked() cache a statement only if
getDelegate().isPoolable() returns true:
modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/StatementCache.java:368
if (getDelegate().isPoolable() && !getDelegate().isCloseOnCompletion()) {
Some drivers always return false from isPoolable() and ignore setPoolable().
H2 and MariaDB Connector/J do. With those, every statement is closed on
close() and the StatementCache interceptor does nothing.
The Javadoc of java.sql.Statement#setPoolable says:
"By default, a Statement is not poolable when created, and a
PreparedStatement and CallableStatement are poolable when created."
https://docs.oracle.com/en/java/javase/21/docs/api/java.sql/java/sql/Statement.html#setPoolable(boolean)
So setPoolable(false) is the application's way to opt out, and what the
driver reports from isPoolable() isn't a reliable signal of that.
To reproduce: configure a pool against H2 with
StatementCache(prepared=true,max=50), prepare a statement, close it, and
check the cache size. It stays 0. In the module itself,
org.apache.tomcat.jdbc.test.TestStatementCache fails on main with 3 failures
(testMaxCacheSize, testPreparedStatementCache, testStatementClose1); they
pass on the parent of bb64a055e2. The test added by that commit
(org.apache.tomcat.jdbc.pool.interceptor.TestStatementCache) uses a mock
statement that returns true from isPoolable(). It is also outside
org/apache/tomcat/jdbc/test/, so the Ant test target doesn't run it.
Proposed fix: track the poolable hint in CachedStatement itself. Default it
to true, update it when the application calls setPoolable() on the proxy
(still passing the call on to the driver), and cache only if it is true and
isCloseOnCompletion() is false. Pull request with tests to follow.
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]