it-roy-ru.com

Закрытие соединений JDBC в пуле

Наш стандартный раздел кода для использования 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. Мы даже не уверены, какая часть исполняется во время выполнения ... Повторяя вопрос выше, нужно ли закрывать соединение, выходящее из такого метода?

Спасибо, - ср.

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

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

97
Manidip Sengupta

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

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


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

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

Смотрите также:

108
BalusC

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

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

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

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

21
taer

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

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

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

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

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

0
Rodney P. Barbati