연결이 닫힌 후에도 JDBC 결과 세트와 명령문을 별도로 닫아야합니까?
사용 후 모든 JDBC 자원을 닫는 것이 좋은 습관이라고합니다. 그러나 다음 코드가있는 경우 결과 집합과 진술을 닫아야합니까?
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = // Retrieve connection
stmt = conn.prepareStatement(// Some SQL);
rs = stmt.executeQuery();
} catch(Exception e) {
// Error Handling
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) {};
try { if (stmt != null) stmt.close(); } catch (Exception e) {};
try { if (conn != null) conn.close(); } catch (Exception e) {};
}
문제는 연결 종료가 작업을 수행하는지 또는 일부 리소스를 사용 중인지 여부입니다.
당신이 한 일은 완벽하고 아주 좋은 연습입니다.
내가 모범 사례를 말하는 이유 ... 예를 들어 어떤 이유로 "기본"유형의 데이터베이스 풀링을 사용하고을 호출 connection.close()
하면 연결이 풀로 리턴되고 ResultSet
/ Statement
는 절대 닫히지 않습니다. 여러 가지 새로운 문제가 발생합니다!
따라서 항상 connection.close()
정리할 필요는 없습니다 .
이게 도움이 되길 바란다 :)
Java 1.7은 try-with-resources 선언문 덕분에 우리의 삶을 훨씬 쉽게 만듭니다 .
try (Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement()) {
try (ResultSet resultSet = statement.executeQuery("some query")) {
// Do stuff with the result set.
}
try (ResultSet resultSet = statement.executeQuery("some query")) {
// Do more stuff with the second result set.
}
}
이 구문은 매우 간단하고 우아합니다. 그리고 그것을 만들 수 없을 connection
때에도 실제로 닫힙니다 statement
.
로부터 의 javadoc :
하면
Statement
개체가 닫혀, 현재ResultSet
존재하는 경우 목적은 역시 폐쇄된다.
그러나 javadocs는 기초를 닫을 때 Statement
및 ResultSet
닫혀 있는지 여부에 대해 명확하지 않습니다 Connection
. 그들은 단순히 Connection을 닫는다 고 말합니다.
이
Connection
오브젝트의 데이터베이스 및 JDBC 자원을 자동으로 해제하기를 기다리지 않고 즉시 해제합니다.
제 생각에는, 항상 명시 적으로 가까운 ResultSets
, Statements
그리고 Connections
당신은의 구현으로 마친 후 close
데이터베이스 드라이버에 따라 다를 수 있습니다.
당신은 같은 방법을 사용하여 자신에게 보일러 플레이트 코드를 많이 절약 할 수 closeQuietly
있는 DBUtils 아파치.
Java와 함께 Oracle을 사용하고 있습니다. 여기 내 관점 :
당신은 닫아야 ResultSet
와 Statement
오라클이 커서를 유지하면서 이전에 문제가 명시 적으로하기 때문에 연결을 종료 후에도 엽니 다. ResultSet
(커서를) 닫지 않으면 최대 열린 커서 초과 와 같은 오류가 발생 합니다.
나는 당신이 사용하는 다른 데이터베이스와 같은 문제가 발생할 수 있다고 생각합니다.
다음은 자습서 닫기 ResultSet가 완료된 후입니다 .
완료되면 ResultSet 닫기
닫기
ResultSet
빨리 작업을 완료 한만큼 객체ResultSet
에도 불구하고 개체Statement
개체가 종료ResultSet
가 폐쇄 닫을 때 암시 적으로 개체가ResultSet
있기 때문에 명시 적으로 가능한 빨리 배열 회수 메모리에 가비지 컬렉터에 기회를 제공ResultSet
개체가 쿼리에 따라 메모리를 많이 차지할 수있다.
ResultSet.close();
더 작은 코드를 원한다면 Apache Commons DbUtils를 사용하는 것이 좋습니다 . 이 경우 :
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = // Retrieve connection
stmt = conn.prepareStatement(// Some SQL);
rs = stmt.executeQuery();
} catch(Exception e) {
// Error Handling
} finally {
DbUtils.closeQuietly(rs);
DbUtils.closeQuietly(stmt);
DbUtils.closeQuietly(conn);
}
JDBC와 관련된 리소스를 닫는 올 바르고 안전한 방법은 다음과 같습니다 ( JDBC 리소스를 올바르게 닫는 방법 – 항상 ).
Connection connection = dataSource.getConnection();
try {
Statement statement = connection.createStatement();
try {
ResultSet resultSet = statement.executeQuery("some query");
try {
// Do stuff with the result set.
} finally {
resultSet.close();
}
} finally {
statement.close();
}
} finally {
connection.close();
}
Connection
풀링 가능 여부 는 중요 하지 않습니다. 풀로 돌아 오기 전에 풀링 가능한 연결도 정리해야합니다.
"청소"는 일반적으로 결과 집합을 닫고 보류중인 트랜잭션을 롤백하지만 연결을 닫지 않으면 풀링이 발생합니다.
일부 편의 기능 :
public static void silentCloseResultSets(Statement st) {
try {
while (!(!st.getMoreResults() && (st.getUpdateCount() == -1))) {}
} catch (SQLException ignore) {}
}
public static void silentCloseResultSets(Statement ...statements) {
for (Statement st: statements) silentCloseResultSets(st);
}
Java 6 양식을 사용하면 닫히기 전에 닫히지 않았는지 확인하는 것이 좋습니다 (예 : 일부 연결 풀러가 다른 스레드에서 연결을 제거하는 경우)-네트워크 문제와 같은 문 및 결과 집합 상태가 닫힐 수 있습니다. (종종 발생하지는 않지만 Oracle 및 DBCP 에서이 문제가 발생했습니다). 내 패턴은 (이전 Java 구문에서) 다음과 같습니다.
try {
...
return resp;
} finally {
if (rs != null && !rs.isClosed()) {
try {
rs.close();
} catch (Exception e2) {
log.warn("Cannot close resultset: " + e2.getMessage());
}
}
if (stmt != null && !stmt.isClosed()) {
try {
stmt.close();
} catch (Exception e2) {
log.warn("Cannot close statement " + e2.getMessage());
}
}
if (con != null && !conn.isClosed()) {
try {
con.close();
} catch (Exception e2) {
log.warn("Cannot close connection: " + e2.getMessage());
}
}
이론적으로는 닫기 상태 점검과 닫기 자체 사이에 상태 변경의 여지가 거의 없기 때문에 100 % 완벽하지 않습니다. 최악의 경우 오랫동안 경고를 받게됩니다. -그러나 장기 쿼리에서 상태가 변경 될 가능성보다 적습니다. 우리는 생산에서 "평균"하중 (150 명의 동시 사용자)으로이 패턴을 사용하고 있으며 아무런 문제가 없었으므로 경고 메시지를 보지 마십시오.
아니요 연결을 닫을 필요는 없습니다. JDBC 사양에 따라 상위 객체를 닫으면 하위 객체가 자동으로 닫힙니다. 닫기 Connection
는 Statement
연결이 생성 한 모든 것을 닫 습니다. 어떤 Statement
것을 닫으면 그에 ResultSet
의해 만들어진 모든 것을 닫을 것 입니다 Statement
. Connection
풀링 가능 여부 는 중요 하지 않습니다. 풀로 돌아 오기 전에 풀링 가능한 연결도 정리해야합니다.
물론 Connection
많은 명령문을 작성 하는 데 긴 중첩 루프가있을 수 있으며 닫는 것이 적절합니다. 나는 거의 결코 가까운 ResultSet
하지만, 닫을 때 과도한 것 Statement
또는 Connection
그것들을 닫습니다.
내가 기억하는 한, 현재 JDBC에서 결과 세트와 명령문은 AutoCloseable 인터페이스를 구현합니다. 즉, 파괴되거나 범위를 벗어나면 자동으로 닫힙니다.
'Programing' 카테고리의 다른 글
HTML5 data- * with asp.net mvc TextboxFor HTML 속성 (0) | 2020.04.12 |
---|---|
문자열 객체와 문자열 리터럴의 차이점 (0) | 2020.04.12 |
PostgreSQL에서 UPSERT (MERGE, INSERT ... ON DUPLICATE UPDATE)하는 방법은 무엇입니까? (0) | 2020.04.12 |
추적되지 않은 파일에 git diff를 사용할 수 있습니까? (0) | 2020.04.12 |
JWT를 해독 할 수 있다면 어떻게 안전합니까? (0) | 2020.04.12 |