WebApp(Tomcat-jdbc)池化数据库连接抛弃exception

我已经浏览了一段时间,并在此过程中咀嚼我的帽子,但找不到与我的问题完全匹配。
简而言之,我在60秒不活动后获得了极好的堆栈跟踪(org.apache.tomcat.jdbc.pool.ConnectionPool放弃),这是几个服务器端线程的正常行为。
我正在使用Tomcat JDBC Connection Pooling(org.apache.tomcat.jdbc.pool.DataSource)
堆栈跟踪:

     2012年10月29日下午8:55:50 org.apache.tomcat.jdbc.pool.ConnectionPool放弃
    警告:连接已被放弃PooledConnection [com.mysql.jdbc.JDBC4Connection@1ad2916]:java.lang.Exception
        在org.apache.tomcat.jdbc.pool.ConnectionPool.getThreadDump(ConnectionPool.java:967)
        在org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:721)
        在org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:579)
        在org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:174)
         at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:111)
        在com.getsom.getConnection(DAO.java:1444)
        在com.getsom.PreparedConnection。(PreparedConnection.java:48)
        在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); 

我希望setValidationInterval(30000)可以节省我,因为30s在连接生命周期中并不多。 无论如何,问题是:
为了让这个连接永远存在,我错过了什么?
很高兴知道:为什么我在声明连接的函数中超时,尽管它是在30秒之前调用的。

尽管我在这个页面上迟到了一年多,但我偶然发现了这个问题,因为我遇到了类似的问题,也需要一个解决方案。 所以我想我会分享最终对我有用的东西。

在我的例子中,在找到并阅读本文>>> configuration-jdbc-pool-high-concurrency之后 – 我刚刚在我的池配置中添加了这样的拦截器;

 "org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer" 

所以你在setJdbcInterceptors(...)所在的行(来自你上面发布的代码setJdbcInterceptors(...)现在应该如下所示;

 p.setJdbcInterceptors( "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;" + "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;" + "org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer"); 

解释 – 从文章中引用,它说;

我们想确保当我们检测到连接仍在使用时,我们重置超时计时器,以便不会将连接视为放弃。 我们通过插入一个拦截器来做到这一点。

每次准备语句或执行查询时,计时器都将重置连接池上的放弃计时器。 这种方式……进行大量查询和更新,不会超时。

请记住,你很可能在很久以前就克服了这个问题,我仍然希望这能帮助其他有类似问题的人碰到这个页面,就像我一样。

干杯!

您是否在Tomcat网站上看​​到了与PoolConnection相关的信息? 也许你需要的是查看属性minEvictableIdleTimeMillis

要回答您的问题,您需要超时,因为您每隔30秒检查一次空闲和放弃连接(请参阅TimeBetweenEvictionRunsMillis ),并且由于您在30秒内设置了一个可逐出的空闲超时(请参阅minEvictableIdleTimeMillis ),然后您最终得到了所拥有的内容。 您已经说过在空闲时收到此exception,我怀疑该exception是关闭空闲连接而不是放弃连接的结果。 根据我的理解,放弃连接用于超时预期查询(与空闲连接相反)。

就个人而言,我不希望永远保持连接,因为它们会不必要地消耗资源(这是与数据库的连接)。 我会玩我的最大连接,驱逐运行和空闲时间来优化我自己的要求。 我想你可以将这些值设置得足够大,几乎可以永远! 它确实取决于你在做什么……

对不起,我在这里得到的帮助不大。

juste在文件conf / server.xml中添加tomcat7

 jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState; org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer; org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer" 

跟踪配置文件中的“removeAbandonedTimeout”。 这应该是应用程序中的最大运行查询。 否则它将在执行过程中关闭连接

如果您在tomcat的context.xml中定义数据源,那么您应该添加ResetAbandonedTimer,如下所示:

 jdbcInterceptors="ConnectionState;StatementFinalizer;ResetAbandonedTimer" 

设置ResetAbandonedTimer之后,问题在我的应用程序中得到解决,请求你让我知道ResetAbandonedTimer拦截器和removeAbandoned =“true”之间是否有任何关系removeAbandonedTimeout =“60”

这个问题的答案对我很有帮助。

虽然在我的情况下,我已经配置了“ResetAbandonedTimer”JDBC Interceptor。

但是,我的查询运行时间超过了我已配置的“removeAbandonedTimeout”。 一旦我增加了“removeAbandonedTimeout”,问题就消失了。