一尘不染

WebApp(Tomcat-jdbc)池化数据库连接抛出放弃异常

tomcat

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

我的PoolProperty配置如下:

    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秒前被调用。


阅读 264

收藏
2020-06-16

共1个答案

一尘不染

即使我迟到了一年以上,但我还是在这里偶然发现了我遇到的类似问题,并且也需要解决方案。所以我想我会分享最终对我有用的东西。

就我而言,在查找并阅读本文>>> configuration-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");

说明 -引用该文章说:

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

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

考虑到您很可能很久以前已经解决了该问题,我仍然希望这可以像本人一样帮助其他遇到类似问题的人进入此页面。

干杯!

2020-06-16