我已经浏览了一段时间,并在此过程中咀嚼我的帽子,但找不到与我的问题完全匹配。
简而言之,我在60秒不活动后获得了极好的堆栈跟踪(org.apache.tomcat.jdbc.pool.ConnectionPool放弃),这是几个服务器端线程的正常行为。
我直接使用Tomcat JDBC连接池(org.apache.tomcat.jdbc.pool.DataSource)
堆栈跟踪:
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);
我希望setValidationInterval(30000)可以节省我,因为30s在连接生命周期中并不多。无论如何,问题是:
为了让这种联系永远存在,我错过了什么?
很高兴知道:为什么我在声明连接的函数中超时,尽管它是在30秒前调用的。
答案 0 :(得分:42)
即使我在这个页面上迟到了一年多,但我偶然发现我遇到了类似的问题,也需要一个解决方案。所以我想我会分享最终对我有用的东西。
就我而言,在找到并阅读本文后,>>> configuring-jdbc-pool-high-concurrency - 我刚刚在我的池配置中添加了这样的拦截器;
"org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer"
以便您setJdbcInterceptors(...)
所在的行(来自您上面发布的代码)现在应该如下所示;
p.setJdbcInterceptors(
"org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
+ "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;"
+ "org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer");
解释 - 引用该文章,它说;
我们要确保当我们检测到连接仍在使用时,我们会重置超时计时器,以便连接不会被视为放弃。我们通过插入一个拦截器来做到这一点。
每次准备语句或执行查询时,计时器都会重置连接池上的放弃计时器。这种方式......进行大量查询和更新,不会超时。
请记住,很久以前你很可能已经克服了这个问题,我仍然希望这可以帮助其他有类似问题的人碰到这个页面,就像我一样。
干杯!
答案 1 :(得分:4)
您是否在Tomcat网站上看到了与PoolConnection相关的信息。也许你需要的是查看属性minEvictableIdleTimeMillis
要回答你的问题,你需要超时,因为你正在检查闲置&每隔30秒放弃一次连接(参见TimeBetweenEvictionRunsMillis
),因为你在30秒内设置了一个可逐出的空闲超时(见minEvictableIdleTimeMillis
),那么你最终会得到你所拥有的。您已经说过在空闲时收到此异常,我怀疑该异常是关闭空闲连接而不是放弃连接的结果。根据我的理解,放弃连接用于超时预期查询(与空闲连接相反)。
我个人不希望永远保持连接,因为它们会不必要地消耗资源(这是与数据库的连接)。我会玩我的最大连接,驱逐运行和空闲时间来优化我自己的要求。我想你可以将这些值设置得足够大,几乎永远!它确实取决于你在做什么......
对不起,我在这里得到了更多的帮助。
答案 2 :(得分:4)
只需在tomcat7 conf / server.xml或context.xml中添加以下条目,无论资源标记存在于何处。
jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;
org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer"
答案 3 :(得分:1)
在配置文件中跟踪'removeAbandonedTimeout'。这应该是应用程序中的最大运行查询。否则它会在执行过程中关闭连接
答案 4 :(得分:1)
如果您在tomcat的context.xml中定义了数据源,那么您应该添加如下的ResetAbandonedTimer:
jdbcInterceptors="ConnectionState;StatementFinalizer;ResetAbandonedTimer"
设置ResetAbandonedTimer后,问题在我的应用程序中得到解决,请求您告诉我ResetAbandonedTimer拦截器与removeAbandoned =“true”之间是否有任何关系removeAbandonedTimeout =“60”
答案 5 :(得分:0)
这个问题的答案对我很有帮助。
虽然在我的情况下,我已经配置了“ResetAbandonedTimer”JDBC拦截器。
但是,我的查询运行时间超过了我已配置的“removeAbandonedTimeout”。一旦我增加了“removeAbandonedTimeout”,问题就消失了。
答案 6 :(得分:0)
有一个类似的问题,即tomcat正在关闭JDBC连接,因为它由于事务花费很长时间而被废弃。
通过意识到abandoned
和idle
不同并设置为spring.datasource.tomcat.removeAbandonedTimeout: 86400 #seconds
答案 7 :(得分:0)
我可以看到此线程很旧,但是我遇到了类似的问题,我最终找到了导致该线程的原因,所以我想分享一下它是否可以帮助某人:
我使用了来自宁静的Web服务的连接。在客户端请求服务器端处理的接口中,我不小心在方法签名中放入了“ throws IOException”:
@GET
@Path("/databases")
@Produces(MediaType.APPLICATION_JSON)
public String getAllDatabases() throws IOException {