WebApp (Tomcat-jdbc) Pooled DB Connection throwing Abandon 异常

2022-09-01 21:52:13

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


答案 1

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

在我的情况下,在找到并通读本文后,>>>配置-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");

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

我们希望确保在检测到连接仍在使用时,重置超时计时器,以便不会将连接视为已放弃。我们通过插入拦截器来实现此目的。

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

请记住,您很可能很久以前就已经克服了这个问题,我仍然希望这有助于其他遇到类似问题的人,就像我一样。

干杯!


答案 2

您是否在Tomcat网站上看到与PoolConnection相关的信息。也许你需要的是看看财产minEvictableIdleTimeMillis

要回答您的问题,您正在超时,因为您每30秒检查一次空闲并放弃连接(请参阅),并且由于您将可逐出的空闲超时设置为30秒(请参阅),那么您最终会得到您所拥有的。您说过您在空闲时收到此异常,我怀疑该异常是关闭空闲连接的结果,而不是放弃连接的结果。根据我的理解,放弃连接用于使查询超时时间长(而不是空闲连接)。TimeBetweenEvictionRunsMillisminEvictableIdleTimeMillis

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

对不起,我在这里不能提供更多的帮助。


推荐