[java] 연결이 닫힌 후에도 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는 기초를 닫을 때 StatementResultSet닫혀 있는지 여부에 대해 명확하지 않습니다 Connection. 그들은 단순히 Connection을 닫는다 고 말합니다.

Connection오브젝트의 데이터베이스 및 JDBC 자원을 자동으로 해제하기를 기다리지 않고 즉시 해제합니다.

제 생각에는, 항상 명시 적으로 가까운 ResultSets, Statements그리고 Connections당신은의 구현으로 마친 후 close데이터베이스 드라이버에 따라 다를 수 있습니다.

당신은 같은 방법을 사용하여 자신에게 보일러 플레이트 코드를 많이 절약 할 수 closeQuietly있는 DBUtils 아파치.


답변

Java와 함께 Oracle을 사용하고 있습니다. 여기 내 관점 :

당신은 닫아야 ResultSetStatement오라클이 커서를 유지하면서 이전에 문제가 명시 적으로하기 때문에 연결을 종료 후에도 엽니 다. 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풀링 가능 는 하지 않습니다. 풀로 돌아 오기 전에 풀링 가능한 연결도 정리해야합니다.

“청소”는 일반적으로 결과 집합을 닫고 보류중인 트랜잭션을 롤백하지만 연결을 닫지 않는 것을 의미합니다. 그렇지 않으면 풀링의 의미가 느슨해집니다.