조금 혼란 스러워요. http://en.wikipedia.org/wiki/Java_Database_Connectivity 에서 아래를 읽고있었습니다 .
Connection conn = DriverManager.getConnection(
"jdbc:somejdbcvendor:other data needed by some jdbc vendor",
"myLogin",
"myPassword" );
Statement stmt = conn.createStatement();
try {
stmt.executeUpdate( "INSERT INTO MyTable( name ) VALUES ( 'my name' ) " );
} finally {
//It's important to close the statement when you are done with it
stmt.close();
}
conn 연결을 닫을 필요가 없습니까? conn.close ()가 발생하지 않으면 실제로 무슨 일이 일어나고 있습니까?
현재 두 양식 중 하나를 닫지 않는 비공개 웹 앱이 있지만 중요한 것은 실제로 stmt 하나, conn 하나 또는 둘 다입니까?
사이트가 간헐적으로 다운되지만 서버는 데이터베이스 연결 문제라고 계속해서 말하고 있습니다. 제 의심은 닫히지 않았다는 것입니다.하지만 어느 쪽을 닫아야할지 모르겠습니다.
답변
사용이 끝나면 연결이 유지하고있을 수있는 다른 데이터베이스 리소스 (커서, 핸들 등)를 해제하기 위해 메서드를 Connection
호출하여 명시 적으로 닫아야합니다 close()
.
사실, 자바의 안전 패턴은 당신이 종료하는 것입니다 ResultSet
, Statement
그리고 Connection
A의 (순서대로) finally
처럼, 블록 당신이 그들과 함께 할 때 뭔가를 :
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// Do stuff
...
} catch (SQLException ex) {
// Exception handling stuff
...
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) { /* ignored */}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) { /* ignored */}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) { /* ignored */}
}
}
finally
블록 약간 (널 검사를 피하기 위해)으로 개선 될 수있다 :
} finally {
try { rs.close(); } catch (Exception e) { /* ignored */ }
try { ps.close(); } catch (Exception e) { /* ignored */ }
try { conn.close(); } catch (Exception e) { /* ignored */ }
}
그러나 여전히 이것은 매우 장황하므로 일반적으로 도우미 클래스를 사용하여 null-safe 도우미 메서드에서 개체를 닫고 finally
블록은 다음과 같이됩니다.
} finally {
DbUtils.closeQuietly(rs);
DbUtils.closeQuietly(ps);
DbUtils.closeQuietly(conn);
}
그리고 실제로 Apache Commons DbUtils 에는 DbUtils
정확하게이를 수행 하는 클래스가 있으므로 직접 작성할 필요가 없습니다.
답변
사용 후에는 항상 데이터베이스 / 리소스 개체를 닫는 것이 좋습니다. finally
블록 에서 연결, 결과 집합 및 문 개체를 닫는 것이 좋습니다.
Java7까지 이러한 모든 리소스는 finally
블록을 사용하여 닫아야합니다 . Java 7을 사용하는 경우 리소스를 닫기 위해 다음과 같이 할 수 있습니다.
try(Connection con = getConnection(url, username, password, "org.postgresql.Driver");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
) {
//statements
}catch(....){}
이제 con, stmt 및 rs 객체는 try 블록의 일부가되고 java는 사용 후 이러한 리소스를 자동으로 닫습니다.
도움이 되었기를 바랍니다.
답변
그냥 닫습니다 충분 Statement
하고 Connection
. ResultSet
개체 를 명시 적으로 닫을 필요가 없습니다 .
Java 문서는 다음에 대해 말합니다 java.sql.ResultSet
.
ResultSet 개체는 해당 Statement 개체가 닫히거나 다시 실행될 때 생성 한 Statement 개체에 의해 자동으로 닫히거나 여러 결과 시퀀스에서 다음 결과를 검색하는 데 사용됩니다.
코멘트에 대해 BalusC에게 감사드립니다 : “나는 그것에 의존하지 않을 것입니다. 일부 JDBC 드라이버는 그것에 실패합니다.”
답변
예. 결과 집합, 문 및 연결을 닫아야합니다. 연결이 풀에서 제공된 경우 연결을 닫으면 실제로 다시 풀로 다시 보내 재사용됩니다.
일반적으로 finally{}
블록 에서이 작업을 수행 해야하므로 예외가 발생하더라도이를 닫을 기회가 있습니다.
많은 프레임 워크가이 리소스 할당 / 할당 해제 문제를 처리합니다. 예 : Spring의 JdbcTemplate . Apache DbUtils 에는 null 여부에 관계없이 결과 집합 / 문 / 연결을 닫은 후 (그리고 닫을 때 예외를 포착하는) 방법이 있습니다.
답변
실제로 try-with-resources 블록을 사용하는 것이 가장 좋으며 try 블록을 종료하면 Java가 모든 연결을 자동으로 닫습니다.
AutoClosable을 구현하는 모든 개체로이 작업을 수행해야합니다.
try (Connection connection = getDatabaseConnection(); Statement statement = connection.createStatement()) {
String sqlToExecute = "SELECT * FROM persons";
try (ResultSet resultSet = statement.execute(sqlToExecute)) {
if (resultSet.next()) {
System.out.println(resultSet.getString("name");
}
}
} catch (SQLException e) {
System.out.println("Failed to select persons.");
}
getDatabaseConnection에 대한 호출이 방금 구성되었습니다. JDBC SQL 연결 또는 풀에서 연결을 가져 오는 호출로 바꾸십시오.
답변
예, 연결을 종료해야합니다. 그렇지 않으면 데이터베이스 클라이언트는 일반적으로 소켓 연결 및 기타 리소스를 열어 둡니다.