Question

Ok, I change my connection factory code, I'm using PoolProperties class and now I'm getting this error:

Data source rejected establishment of connection, message from server: "Too many connections"

In my InsertandGetObject Method I log a message in order to test that the connection is closing and it is, I also debbug on server.

Any ideas for this issue? :s

This is my connection Pool:

    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;
}

This is the method that close the connection:

    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;
}
Was it helpful?

Solution

With new DataSource(PoolProperties) you do not create a "DataSource object wrapping a connection" (as stated in the ApiDocs). Instead, you create a pool of connections (also mentioned in the ApiDocs, but at the top: "The DataSource simply wraps a ConnectionPool ..."). I verified this in, what I think is, the source code (see line 108 of DataSourceProxy).

Consequently, closing a Connection only returns it to the pool (so it can be re-used), it does not actually close the connection (unless you see the connection actually being closed on the database server, in which case I'm wrong). Solution is to create 1 DataSource object and re-use it for each getConnection() call. Close the DataSource/ConnectionPool when the application no longer needs a database connection.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top