Mon*_*ded 21 java mysql tomcat connection-pooling
我已经浏览了一段时间,并在此过程中咀嚼我的帽子,但无法找到与我的问题完全匹配.
简而言之,我在60秒不活动后获得了极好的堆栈跟踪(org.apache.tomcat.jdbc.pool.ConnectionPool放弃),这是几个服务器端线程的正常行为.
我直接使用Tomcat JDBC连接池(org.apache.tomcat.jdbc.pool.DataSource)
Stack Trace:
Oct 29, 2012 8:55:50 PM org.apache.tomcat.jdbc.pool.ConnectionPool abandon WARNING: Connection has been abandoned PooledConnection[com.mysql.jdbc.JDBC4Connection@1ad2916]:java.lang.Exception at org.apache.tomcat.jdbc.pool.ConnectionPool.getThreadDump(ConnectionPool.java:967) at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:721) at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:579) at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:174) at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:111) at com.getsom.getConnection(DAO.java:1444) at com.getsom.PreparedConnection.(PreparedConnection.java:48) at com.getsom.Alarms.run(Alarms.java:492)
我的PoolProperties配置如下:
PoolProperties pp = new PoolProperties();
pp.setUrl( someValidUrl);
pp.setDriverClassName("com.mysql.jdbc.Driver");
pp.setUsername( someUser);
pp.setPassword( somePassword);
pp.setJmxEnabled( true);
pp.setTestWhileIdle( true);
pp.setTestOnBorrow( true);
pp.setValidationQuery( "SELECT 1");
pp.setTestOnReturn( false);
pp.setValidationInterval(30000);
pp.setTimeBetweenEvictionRunsMillis(30000);
pp.setMaxActive(100);
pp.setInitialSize(10);
pp.setMaxWait(10000);
pp.setMinEvictableIdleTimeMillis(30000);
pp.setMinIdle(10);
pp.setLogAbandoned(true);
pp.setRemoveAbandoned(true);
pp.setRemoveAbandonedTimeout(60);
pp.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
"org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
setPoolProperties(pp);
Run Code Online (Sandbox Code Playgroud)
我希望setValidationInterval(30000)可以节省我,因为30s在连接生命周期中并不多.无论如何,问题是:
我错过了什么让这个连接永远存在?
很高兴知道:为什么我在声称连接的函数中超时,尽管它是在30秒之前调用的.
tec*_*rat 45
尽管我在这个页面上来的时间已经超过1年了,但我偶然发现了这个问题,因为我遇到了类似的问题并且需要一个解决方案.所以我想我会分享最终对我有用的东西.
在我的例子中,在查找并阅读了本文>>> configuration-jdbc-pool-high-concurrency之后 - 我刚刚在我的池配置中添加了这样的拦截器;
"org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer"
Run Code Online (Sandbox Code Playgroud)
所以你所在的那一行(来自你上面发布的代码)setJdbcInterceptors(...)
现在应该如下所示;
p.setJdbcInterceptors(
"org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
+ "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;"
+ "org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer");
Run Code Online (Sandbox Code Playgroud)
解释 - 从文章中引用,它说;
我们想确保当我们检测到连接仍在使用时,我们重置超时计时器,以便连接不被视为放弃.我们通过插入一个拦截器来做到这一点.
每次准备语句或执行查询时,计时器都将重置连接池上的放弃计时器.这种方式......进行大量查询和更新,不会超时.
请记住,你很可能在很久以前就克服了这个问题,我仍然希望这能帮助其他有类似问题的人碰到这个页面,就像我一样.
干杯!
您是否看过 Tomcat 网站上有关PoolConnection的信息。也许你需要的是看看房产minEvictableIdleTimeMillis
要回答您的问题,您正在超时,因为您每 30 秒检查一次空闲和放弃连接(请参阅TimeBetweenEvictionRunsMillis
),并且由于您将可逐出的空闲超时设置为 30 秒(请参阅minEvictableIdleTimeMillis
),那么您最终会得到您所拥有的。您说过您在空闲时收到此异常,我怀疑该异常是关闭空闲连接而不是放弃连接的结果。根据我的理解,放弃连接用于超时时间超过预期的查询(而不是空闲连接)。
就我个人而言,我不希望连接永远存在,因为它们会不必要地消耗资源(即与数据库的连接)。我会调整我的最大连接数、逐出运行和空闲时间,以根据我自己的要求进行优化。我想你可以将这些值设置得足够大,几乎永远!这确实取决于你在做什么......
抱歉,我无法在这里提供更多帮助。