【问题标题】:Too many connections (New Error)连接过多(新错误)
【发布时间】:2014-04-21 05:42:34
【问题描述】:

好的,我更改了我的连接工厂代码,我正在使用 PoolProperties 类,现在我收到了这个错误:

数据源拒绝建立连接,来自服务器的消息:“连接太多”

在我的 InsertandGetObject 方法中,我记录了一条消息以测试连接是否正在关闭,我还在服务器上进行调试。

对这个问题有什么想法吗? :s

这是我的连接池:

    public static Connection getConnection() throws DatabaseConnectionException {

    PoolProperties p = new PoolProperties();
    p.setName("jdbc/MetaData");
    p.setUrl("jdbc:mysql://localhost:3306/db_name");
    p.setDriverClassName("com.mysql.jdbc.Driver");
    p.setUsername("root");
    p.setPassword("");
    p.setInitialSize(3);
    p.setMaxActive(10);
    p.setMaxIdle(8);
    p.setMinIdle(2);
    p.setRemoveAbandoned(true);
    p.setMaxWait(10000);

    Connection conn = null;



    try {

        DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource(p);

        conn = dataSource.getConnection();

    } catch (SQLException e) {
        LOGGER.debug("MSJ SQLExp: " + e.getMessage());
        throw new DatabaseConnectionException(e);

    } 

    return conn;
}

这是关闭连接的方法:

    public Concept insertAndGetObject(Concept object) throws SQLException,
        DatabaseConnectionException {
    try {

        connection = ConnectionFactory.getConnection();
        connection.setAutoCommit(false);
        statement = connection.prepareStatement(INSERT_CONCEPTS);
        statement = ConceptMapperUtil.setStatementParameters(statement,
                object);
        statement.executeUpdate();
        connection.commit();
        LOGGER.debug("Inserted concept row ");
    } catch (SQLException e) {
        connection.rollback();

        if (e.getErrorCode() == SQL_INSERT_ERROR_CODE) {
            LOGGER.debug("Concept already exists!");
        } else {
            throw e;
        }

    } finally {
        object = findConceptByUniqueFk(object.dataSource.getIdDataSource(),
                object.conceptType.getIdConcept(),
                object.idMetadataVersion.getIdMetaDataVersion());
        DbUtil.close(statement);
        // connection.setAutoCommit(true);
        DbUtil.close(connection);
    }
    return object;
}

【问题讨论】:

  • 不严格与您的问题有关,但是您为什么(1)在方法的开头没有得到Concept,以避免将异常用作“正常”业务逻辑(插入一个已经存在的概念在您的流程中是“正常的”)和(2)当有可能引发严重的 SQLException 并且您的连接处于无效状态时,在 finally 子句中返回数据库?这第二点甚至可以解释你的问题,虽然我不能用你到目前为止提供的信息来判断。
  • 我做了一些更改,现在我得到了这个错误,你知道吗?
  • 您的应用程序正在接收多少请求(或同时请求)?您的数据库配置为处理多少个同时连接?尝试增加mysql允许的连接数(通过mysql管理员或编辑my.ini)
  • 在您的 finally 块中,您连续调用 DbUtil.close 两次 DbUtil.close(statement) -> 首先(使用语句作为参数),然后调用 DbUtil.close(connection),这一次将连接作为参数传递

标签: java tomcat connection-pooling


【解决方案1】:

使用new DataSource(PoolProperties),您不会创建“包装连接的数据源对象”(如ApiDocs 中所述)。相反,您创建了一个连接池(在 ApiDocs 中也提到过,但在顶部:“DataSource 简单地包装了一个 ConnectionPool ...”)。我在我认为的源代码中验证了这一点(参见DataSourceProxy 的第 108 行)。

因此,关闭连接只会将它返回到池中(因此它可以被重复使用),它实际上并没有关闭连接(除非你看到连接实际上在数据库服务器上被关闭,在这种情况下我'我错了)。解决方案是创建 1 个 DataSource 对象并为每个 getConnection() 调用重新使用它。当应用程序不再需要数据库连接时,关闭 DataSource/ConnectionPool。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    • 1970-01-01
    • 2013-05-17
    相关资源
    最近更新 更多