Tomcat JDBC pool reaches maxActive while abandoned connections await removal
0 reputation · 28 Dec 2023, 16:01 UTC
0 reputation · 28 Dec 2023, 16:01 UTC
Choose removeAbandonedTimeout for the org.apache.tomcat.jdbc.pool.DataSourceFactory pool so leaked checkouts are reclaimed without interrupting legitimate long-running transactions.
removeAbandoned must be true for removal, and abandonWhenPercentageFull plus removeAbandonedTimeout decide when a checked-out connection is abandoned. A timeout shorter than the longest transaction can interrupt active work; a timeout too long lets leaked connections accumulate until maxActive rejects new requests. Defaults and attribute availability vary by Tomcat version. Confirm the factory class and attribute names for the version in use. logAbandoned stack traces identify the leaking code path but add checkout overhead under concurrency. Resource settings in context.xml or server.xml are not interchangeable with Commons DBCP or HikariCP properties.
What is the safest way to bound removeAbandonedTimeout against observed transaction durations without prior production incident data?
Should abandonWhenPercentageFull be tuned before enabling removeAbandoned, or does removal depend primarily on the timeout?
How does enabling logAbandoned change the leak-detection trade-off in a high-concurrency web application?
35275 reputation · 28 Dec 2023, 18:59 UTC
Bound removeAbandonedTimeout by the longest legitimate transaction duration plus a safety margin, not by maxActive alone. Enable removeAbandoned, keep abandonWhenPercentageFull at 0 initially, and treat logAbandoned as a temporary diagnostic. I am assuming the Tomcat JDBC pool factory org.apache.tomcat.jdbc.pool.DataSourceFactory on Tomcat 8.5/9/10/11; attribute names and defaults vary by release, so verify them against the documentation for the deployed version.
removeAbandoned must be true before any checked-out connection can be reclaimed.removeAbandonedTimeout is the primary age threshold. abandonWhenPercentageFull is a secondary utilization gate: when set greater than 0, cleanup runs only after utilization reaches that percentage of maxActive.maxActive exhaustion is caused by leaked checkouts that never return, eventually making the pool reject new requests. Confirm this with JMX before changing the timeout.<Resource name='jdbc/AppDB'
factory='org.apache.tomcat.jdbc.pool.DataSourceFactory'
type='javax.sql.DataSource'
removeAbandoned='true'
removeAbandonedTimeout='600'
abandonWhenPercentageFull='0'
logAbandoned='false' />
Replace 600 with the computed seconds. If your Tomcat build does not accept abandonWhenPercentageFull='0', omit it and verify the attribute in the version-specific documentation.
No. Removal depends primarily on removeAbandoned plus removeAbandonedTimeout. Tune abandonWhenPercentageFull only after basic reclamation behavior is stable; use it to reduce sweep frequency when the pool is healthy, not as the primary leak control.
logAbandoned preserves the borrowing stack trace so the log identifies the code path that failed to close the connection. That is valuable, but it adds per-checkout bookkeeping and logging cost during reclamation. In a high-concurrency web application, leave it disabled in steady-state production and enable it temporarily in staging or during a short diagnostic window.
numActive, numIdle, and pool size; compare peak active connections with maxActive.context.xml or server.xml; do not substitute Commons DBCP or HikariCP property names.One diagnostic detail would change the recommendation: whether exhaustion occurs with numActive pinned near maxActive and numIdle near zero, or as short spikes that recover on their own.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.