Закрытие соединений 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: при использовании пула соединений следует закрыть соединение в конце? Если да, то разве цель объединения не потеряна? А если нет, то как источник данных узнает, когда конкретный экземпляр соединения освобождается и может быть использован повторно? Я немного запутался в этом, любые указатели оценили.
Вопрос 2: является ли следующий метод чем-то близким к стандартному? Похоже на попытку получить подключение из пула, и если источник данных не может быть установлен, используйте старомодный 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);
}
Edit: я думаю, что мы получаем соединение в пуле, так как мы не видим трассировку стека.
3 ответа:
при использовании пула соединений следует закрыть соединение в конце? Если да, то разве цель объединения не потеряна? А если нет, то как источник данных узнает, когда конкретный экземпляр соединения освобождается и может быть использован повторно? Я немного запутался в этом, любые указатели оценили.
Да, конечно, вам также нужно закрыть соединение в пуле. Это на самом деле обертка вокруг фактического соединения. Это будет под одеялом отпустите фактическое соединение обратно в пул. Это дальше до пула, чтобы решить, будет ли фактическое соединение на самом деле закрыть или повторно использовать для нового
getConnection()
звонок. Таким образом, независимо от того, используете ли вы пул соединений или нет, вы должны всегда закройте все ресурсы JDBC в обратном порядке вfinally
блокtry
блок, где вы приобрели их. В Java 7 это может быть упрощен с помощьюtry-with-resources
заявление.
является ли следующий метод чем-то близким к стандартному? Похоже на попытку получить соединение из пула, и если источник данных не может быть установлен, используйте старомодный DriverManager. Мы даже не уверены, какая часть выполняется во время выполнения. Повторяя вопрос выше, нужно ли закрывать соединение, выходящее из такого метода?
пример довольно страшно. Вам просто нужно поиск / инициализация
DataSource
только один раз во время запуска приложения в каком-либо конструкторе / инициализации класса конфигурации БД applicationwide. Тогда просто позвонитеgetConnection()
на одном и том же источнике данных на протяжении всего оставшегося срока службы приложения. Нет необходимости в синхронизации или nullchecks.Читайте также:
пулы обычно возвращают вам обернутый объект соединения, где метод close () переопределяется, обычно возвращая соединение в пул. Вызов close () в порядке и, вероятно, все еще требуется.
метод close (), вероятно, будет выглядеть так:
public void close() throws SQLException { pool.returnConnection(this); }
для вашего второго вопроса Вы можете добавить регистратор, чтобы показать, работает ли нижний блок. Я бы предположил, что вы хотите только так или иначе для конфигурации своей базы данных подключение. Мы используем только пул для доступа к нашей базе данных. В любом случае, закрытие соединения было бы очень важно для предотвращения утечек.
на самом деле, лучший подход к управлению соединениями-это не передавать их в какой-либо код в любом месте.
создайте класс SQLExecutor, который является единственным местоположением, которое открывает и закрывает соединения.
вся остальная часть приложения затем перекачивает операторы в исполнитель, а не получает соединения из пула и управляет (или неправильно управляет ими) повсюду.
вы можете иметь столько экземпляров исполнителя, сколько хотите, но никто не должен писать код, который открывает и закрывает подключения от своего имени.
удобно, это также позволяет вам регистрировать все ваши SQL из одного набора кода.