Закрытие соединений JDBC в пуле - PullRequest
99 голосов
/ 09 февраля 2011

Наш стандартный кодовый раздел для использования JDBC: ...

Connection conn = getConnection(...);
Statement  stmt = conn.conn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
                                                ResultSet.CONCUR_READ_ONLY);
ResultSet  rset = stmt.executeQuery (sqlQuery);

// do stuff with rset

rset.close(); stmt.close(); conn.close();

Вопрос 1: При использовании пула соединений нужно ли закрывать соединение в конце?Если так, разве цель объединения не потеряна?И если нет, то как DataSource узнает, когда конкретный экземпляр Connection освобожден и может быть повторно использован?Я немного запутался в этом вопросе, любые указатели оценены.

Вопрос 2: Является ли следующий метод чем-то близким к стандартному?Похоже на попытку получить соединение из пула, и если DataSource не может быть установлен, используйте старомодный DriverManager.Мы даже не уверены, какая часть исполняется во время выполнения.Повторяя вопрос выше, нужно ли закрывать соединение, выходящее из такого метода?

Спасибо, - MS.

synchronized public Connection getConnection (boolean pooledConnection)
                                                        throws SQLException {
        if (pooledConnection) {
                if (ds == null) {
                        try {
                                Context envCtx = (Context)
                                        new InitialContext().lookup("java:comp/env");
                                ds = (DataSource) envCtx.lookup("jdbc/NamedInTomcat");
                                return ds.getConnection();
                        } catch (NamingException e) {
                                e.printStackTrace();
                }}
                return (ds == null) ? getConnection (false) : ds.getConnection();
        }
        return DriverManager.getConnection(
                "jdbc:mysql://"+ipaddy+":"+dbPort +"/" + dbName, uName, pWord);
}

Редактировать: Я думаю, что мы получаем пул соединения, так как мыне видеть трассировку стека.

Ответы [ 3 ]

110 голосов
/ 09 февраля 2011

При использовании пула соединений следует ли закрывать соединение в конце?Если так, разве цель объединения не потеряна?И если нет, то как DataSource узнает, когда конкретный экземпляр Connection освобожден и может быть повторно использован?Я немного запутался в этом, все указатели оценены.

Да, конечно, вам также необходимо закрыть пул соединения.Это фактически обертка вокруг фактического соединения.Под крышками освободится фактическое соединение с бассейном.Далее пул должен решить, будет ли фактическое соединение фактически закрыто или повторно использовано для нового вызова getConnection().Таким образом, независимо от того, используете ли вы пул соединений или нет, вы должны всегда закрывать все ресурсы JDBC в обратном порядке в блоке finally блока try, где вы их получили,В Java 7 это можно еще более упростить, используя оператор try-with-resources.


Является ли следующий метод чем-то близким к стандартному?Похоже на попытку получить соединение из пула, и если DataSource не может быть установлен, используйте старомодный DriverManager.Мы даже не уверены, какая часть исполняется во время выполнения.Повторяя вопрос выше, нужно ли закрывать Connection, выходящий из такого метода?

Пример довольно страшный.Вам просто нужно искать / инициализировать DataSource только один раз во время запуска приложения в каком-либо конструкторе / инициализации класса конфигурации БД всего приложения.Затем просто вызовите getConnection() на одном и том же источнике данных в течение оставшейся части жизни приложения.Нет необходимости ни в синхронизации, ни в нулевых проверках.

См. Также:

21 голосов
/ 09 февраля 2011

Пулы обычно возвращают вам упакованный объект Connection, где метод close () переопределяется, обычно возвращая Connection к пулу. Вызов close () в порядке и, вероятно, все еще требуется.

Метод close (), вероятно, будет выглядеть так:

public void close() throws SQLException {
  pool.returnConnection(this);
}

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

0 голосов
/ 11 октября 2018

На самом деле, лучший подход к управлению соединениями - не размещать их ни в каком коде.

Создайте класс SQLExecutor, который является единственным местоположением, которое открывает и закрывает соединения.

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

Вы можете иметь столько экземпляров executor, сколько захотите, но никто не должен писать код, который открывает и закрывает соединения от своего имени.

Удобно, что это также позволяет вам регистрировать весь ваш SQL из единого набора кода.

...