Вопрос по database, java, oracle, jdbc – Java / JDBC: лучший шаблон проектирования для закрытия соединения с базой данных при возникновении исключения
Я новичок в Java (я использую Java 6). Я использовал приведенный ниже шаблон проектирования для всех моих Java POJO и сервлетов для доступа к базе данных Oracle 11G через веб-сервер GlassFish 3.1.2.
Я получаю неустойчивую ошибку базы данных (ORA-12519), когда все доступные процессы (или сеансы, не уверен, в чем разница) используются, что заставляет меня думать, что процессы не освобождаются приложением.
Глядя на шаблон проектирования ниже, есть ли лучший способ убедиться, что соединение JDBC с базой данных освобождается в случае исключения? Например, я должен также разместитьif ( conn != null) conn.close();
код ВНУТРИ блока catch? Или есть лучший дизайн шаблона? Заранее спасибо за любые комментарии / подсказки.
public String MyFunction() throws Exception {
Connection conn;
CallableStatement cs;
try {
Context context = new InitialContext();
DataSource ds = (DataSource)context.lookup("jdbc/MyPool");
conn = ds.getConnection();
cs = conn.prepareCall( "{call my_sproc (?)}" );
cs.registerOutParameter(1, Types.VARCHAR);
cs.execute();
String outParam = cs.getString(1);
if ( conn != null ) // close connection
conn.close();
} catch (Exception e) {
outParam = "an error occurred";
}
return outparam;
}
if ( conn != null ) // close connection
conn.close();
На этой линииconn
cannot быть нулевым Самый популярный шаблон вплоть до Java 6:
Connection conn = null;
try {
// initialize connection
// use connection
} catch {
// handle exception
} finally {
if (conn != null) {
try { conn.close(); } catch (Exception e) { /* handle close exception, quite usually ignore */ }
}
}
СJava 7 это станет менее громоздким с егопопробуйте-с ресурсом построить. Приведенный выше код может измениться на гораздо более короткий
try (Connection conn = createConnection()) {
// use connection
} catch {
// handle exception
}
// close is not required to be called explicitly
connection.close()
часто игнорируются или по большей части регистрируются, но не обрабатываются каким-либо другим способом :) Я не знаю, почему; На самом деле я никогда не видел, чтобы близкие бросали исключение.
try...catch
в блоке finally (то естьif (conn != null) conn.close();
всегда там, верно?) Почему люди обычно игнорируют обработку исключения в блоке finally для закрытия соединения?
Я предпочитаю другой более элегантный способ, чем:
} finally {
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
/* handle close exception, quite usually ignore */
}
}
}
Вы можете использовать DbUtils.closeQuietly:http://commons.apache.org/dbutils/apidocs/org/apache/commons/dbutils/DbUtils.html
Использоватьfinally
блокировать всегда, чтобы высвободить ресурсы.
The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs.
try {
Context context = new InitialContext();
DataSource ds = (DataSource)context.lookup("jdbc/MyPool");
conn = ds.getConnection();
cs = conn.prepareCall( "{call my_sproc (?)}" );
cs.registerOutParameter(1, Types.VARCHAR);
cs.execute();
String outParam = cs.getString(1);
} catch (Exception e) {
outParam = "an error occurred";
}
finally {
conn.close();
}
conn.close()
снова выдаст ошибку, окружите ееtry catch finally
также.
conn != null
; может быть нулевым, еслиds.getConnection()
выбрасывает исключение. И будь вы подозреваете или нет, вам нужно поставитьclose()
вtry/catch/finally
; иначе метод должен включить его в свойthrows
пункт, который не хорошо.
conn.close()
строка кода в блоке finally выдает ошибку, если соединение еще не открыто или по какой-либо другой причине? Если да, то я не должен использовать этоif (conn!=null)
утверждение выше в блоке finally?
Java 7 поддерживает функцию пробного использования ресурсов. это создает окончательно для вас.http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Блок finally закроет ресурсы, выделенные в попытке. как вы использовали ключевое слово, используя в C #
Однако пользователь использует Java SE6 ... Смотрите параметры других пользователей :)
ВАЖНО: Используемые заявления также должны быть закрыты.
Connection
не говорите, что закрытиеConnection
закрывает егоStatements
; но обратите внимание, что закрытиеStatement
is требуется закрытьResultSets