Методы объединения Подключения mysql JDBC для предотвращения исчерпанного пула соединения

У меня есть веб-приложение Java-JSF на GlassFish, в котором я хочу использовать организацию пула подключений. Поэтому я создал application ограниченный по объему боб, который служит с Connection экземпляры для других бобов:

public class DatabaseBean {

    private DataSource myDataSource;

    public DatabaseBean() {
        try {
            Context ctx = new InitialContext();
            ecwinsDataSource = (DataSource) ctx.lookup("jdbc/myDataSource");
        } catch (NamingException ex) {
            ex.printStackTrace();
        }
    }

    public Connection getConnection() throws ClassNotFoundException, SQLException, InstantiationException, IllegalAccessException {
        Connection connection = myDataSource.getConnection();
        System.out.println("Succesfully connected: " + connection);
        //Sample: Succesfully connected: com.sun.gjc.spi.jdbc40.ConnectionHolder40@7fb213a5
        return connection;
    }
}

Таким образом, пул соединения заполняется очень быстро; после некоторых навигация посредством 'связанных с дб' представлений приложение останавливается со следующим:

RAR5117: Не удалось получить/создать соединение из пула соединения [mysql_testPool]. Причина: используемые соединения равный макс. размер пула и истекли макс. время ожидания. Не может выделить больше соединений. RAR5114: Ошибка, выделяющая соединение: [Ошибка в выделении соединения. Причина: используемые соединения равный макс. размер пула и истекли макс. время ожидания. Не может выделить больше соединений.] java.sql. SQLException: Ошибка в выделении соединения. Причина: используемые соединения равный макс. размер пула и истекли макс. время ожидания. Не может выделить больше соединений.

Я закрываю соединения и другие ресурсы в каждом методе. Выполнение приложения весь OK с автономными соединениями.

Что я делаю неправильно? Любые подсказки или совет ценились бы.

10
задан BalusC 4 February 2016 в 17:25
поделиться

2 ответа

Исключение указывает на типичный случай кода приложения, который приводит к утечке соединений с базой данных. Вам необходимо убедиться, что вы приобрели и закрыли все из них ( Connection , Statement и ResultSet ) в попытке with-resources в том же самом блоке метода в соответствии с обычной идиомой JDBC.

public void create(Entity entity) throws SQLException {
    try (
        Connection connection = dataSource.getConnection();
        PreparedStatement statement = connection.prepareStatement(SQL_CREATE);
    ) { 
        statement.setSomeObject(1, entity.getSomeProperty());
        // ...
        statement.executeUpdate();
    }
}

Или, когда вы не используете Java 7, в блоке try-finally . Закрытие их в finally гарантирует, что они также будут закрыты в случае исключений.

public void create(Entity entity) throws SQLException {
    Connection connection = null;
    PreparedStatement statement = null;

    try { 
        connection = dataSource.getConnection();
        statement = connection.prepareStatement(SQL_CREATE);
        statement.setSomeObject(1, entity.getSomeProperty());
        // ...
        statement.executeUpdate();
    } finally {
        if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
        if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
    }
}

Да, вам все равно нужно закрывать соединения самостоятельно, даже при использовании пула соединений. Среди новичков распространена ошибка, когда они думают, что затем закрытие будет выполнено автоматически. Это неправда . Пул соединений возвращает завернутое соединение, которое делает что-то вроде следующего в close ():

public void close() throws SQLException {
    if (this.connection is still eligible for reuse) {
        do not close this.connection, but just return it to pool for reuse;
    } else {
        actually invoke this.connection.close();
    }
}

Если их не закрыть, соединение не будет возвращено в пул для повторного использования, и, таким образом, оно будет получать новое снова и снова. до тех пор, пока в БД не закончатся соединения, что приведет к сбою вашего приложения.

См. Также:

20
ответ дан 3 December 2019 в 19:32
поделиться

Если вам нужен пул соединений JDBC, почему бы вам не полагаться на то, что уже доступно? AFAIK, пул соединений JDBC считается более или менее стандартной функцией на этих серверах приложений Java, и IMO, вам не следует создавать это самостоятельно, если вы просто заинтересованы в создании приложения.

Вот ссылка, с которой вы должны начать: http://weblogs.java.net/blog/2007/09/12/totd-9-using-jdbc-connection-pooljndi- name-glassfish-rails-application

Вероятно, вам следует выяснить, как позволить вашему приложению получать соединение из пула с помощью jndi.

0
ответ дан 3 December 2019 в 19:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: