WebApp(Tomcat-jdbc)汇集数据库连接抛弃异常

问题描述 投票:18回答:7

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

java mysql tomcat connection-pooling
7个回答
43
投票

尽管我在这个页面上来的时间已经超过1年了,但我偶然发现了这个问题,因为我遇到了类似的问题并且需要一个解决方案。所以我想我会分享最终对我有用的东西。

在我的例子中,找到并阅读了这篇文章>>> 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");

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

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

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

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

干杯!


4
投票

您是否看过Tomcat网站上有关PoolConnection的信息?也许你需要的是看看物业minEvictableIdleTimeMillis

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

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

对不起,我在这里帮助不多了。


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"

1
投票

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


1
投票

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

jdbcInterceptors="ConnectionState;StatementFinalizer;ResetAbandonedTimer"

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


0
投票

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

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

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


0
投票

有一个类似的问题,即,由于事务花了很长时间,tomcat因为它被放弃而关闭了JDBC连接。

通过认识到abandonedidle不同并通过设置来解决它:spring.datasource.tomcat.removeAbandonedTimeout: 86400 #seconds

© www.soinside.com 2019 - 2024. All rights reserved.