문제

내가 하고 있는 코드를 검토(대부분과 같은 도구를 사용하여 FindBugs)중 하나의 우리의 애완 동물 프로젝트 및 FindBugs 표시된 다음 코드의 잘못된 것으로(사):

Connection conn = dataSource.getConnection();

try{
    PreparedStatement stmt = conn.prepareStatement();
    //initialize the statement
    stmt.execute();
    ResultSet rs =  stmt.getResultSet();
    //get data
}finally{
    conn.close();
}

오류가 이 코드지 않을 수도 있습 릴리스 리소스입니다.제가 생각한 것 ResultSet 및 문었다 닫지 않도록 그들을 폐쇄에 마지막으로:

finally{
    try{
        rs.close()
    }catch(SqlException se){
        //log it
    }
    try{
        stmt.close();
    }catch(SqlException se){
        //log it
    }
    conn.close();
}

하지만 내가 발생 위의 패턴에 많은 프로젝트(에서 몇몇 회사),한 말을 닫는 결과 또는 문입니다.

당신은 문제가 결과 및 문지 않는 폐쇄 할 때 연결이 닫혔습니까?

내가 발견만 그리고 그것은 오라클 문제가 있으로 닫는 결과를 닫을 때 연결(우리가 사용하여 Oracle db,따라서 내 수정).java.sql.api 아무것도 말에 연결합니다.close()javadoc.

도움이 되었습니까?

해결책

하나의 문제로만 연결을 닫고지 않은 결과로 설정,는 경우 연결을 관리 코드를 사용하여 연결 풀링 connection.close() 그냥 넣어 다시 연결되어 있습니다.또한 일부 데이터베이스 커서를 자원하는 서버에서이 해제되지 않습을 제대로 하지 않는 한 그것은 명시적으로 폐쇄했다.

다른 팁

내가 문제가 있었으로 닫히지 않은 결과에서 오라클에도 연결이 닫혔습니다.는 오류도

"ORA-01000: maximum open cursors exceeded"

그래서:항상 가까이 당신의 ResultSet!

당신은 항상을 모두 닫 JDBC 자원이 명시적으로 합니다.아론의와 요한이 이미 말했듯이,닫 연결 것입니다 종종 그것을 반환을 수영장되지 않은 JDBC 드라이버가 구현되는 정확히 동일한 방법입니다.

여기에는 유틸리티는 방법이 사용될 수 있습에서 마지막으로 블록

public static void closeEverything(ResultSet rs, Statement stmt,
        Connection con) {
    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException e) {
        }
    }
    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException e) {
        }
    }
    if (con != null) {
        try {
            con.close();
        } catch (SQLException e) {
        }
    }
}

Oracle 줄 것입니다 당신의 오류에 대한 열려있는 커서 이 경우.

에 따르면: http://java.sun.com/javase/6/docs/api/java/sql/Statement.html

그것처럼 보이는 재사용하는 문을 닫을 것이 열려 있는 모든 결과,고 닫고 문을 닫는 모든 결과,그러나 나는 아무 것도 보이지 않으 폐쇄에 관한 연결을 닫을 것이의 모든 리소스를 만들어집니다.

모든 사람들의 세부 사항은 JDBC 드라이버에 대한 공급자입니다.

그는 항상 안전을 닫는 모든 명시적으로 합니다.우리가 쓴 util 클래스는 랩으로 모든 것을 하려고{xxx}catch(Throwable{}할 수 있도록 전화 Utils.close(rs)및 Utils.close(stmt),등등에 대해 걱정할 필요없이 예외는 아마 검색니다.

ODBC 다리를 생산할 수 있는 메모리 누수가 일부 ODBC 드라이버가 있습니다.

를 사용하면 좋은 JDBC 드라이버 그럼 당신은 어떤 문제가 발생하지 않는 폐쇄와 함께 연결합니다.그러나 거기에는 2 개의 문제점:

  • 는 당신이 알고 있는 경우에 당신은 좋은 드라이버입니까?
  • 을 사용할 것 다른 JDBC 드라이버에서 미래는?

는 것이 가장 좋습니다 그것을 닫습니다.

서 큰 J2EE 웹 환경이다.우리는 여러 가지는 데이터베이스에 연결 될 수 있습에서 하나의 요청을 합니다.우리가 시작했을 논리적 교착 상태에서 우리의 일부 응용 프로그램.문제는 다음과 같다:

  1. 사용자가 요청 페이지
  2. 서버 연결로 DB1
  3. 서버에서 선택 DB1
  4. "서버를 닫"연결하여 DB1
  5. 서버 연결로 DB2
  6. 교착 상태!

이에 대해 발생한 2 가지 이유로,우리가 경험하고 훨씬 더 높은 볼륨 트래픽의 정상 J2EE Spec 기본적으로하지 않는 실제로 연결 될 때까지 스레드가 완료되어 실행이 가능합니다.그래서 위의 예에서 4 단계로 결코 실제로 연결을 닫았지만 그들이 제대로 닫히에 마지막으로.

이 문제를 해결하려면,당신은 당신이 사용하는 리소스에 참조 web.xml 데이터베이스에 대한 연결과를 설정할 필요가 있습니다 res 공유 범위를 unsharable.

예제:

<resource-ref>
    <description>My Database</description>
    <res-ref-name>jdbc/jndi/pathtodatasource</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>

나는 확실히 볼 수 있는 문제로 닫히지 않은 결과와 그것은 무엇을 해칠 수 있는 그들을 닫는 모든 시간,오른쪽?신뢰성의 필요를 기억하는 이렇게 하는 가장 좋은 이유 중 하나로 이동하려면 프레임워크를 관리하는 당신을 위해 이러한 정보를 확보.되지 않을 수도 있습니다 가능한 개발 환경에서,하지만 나는 큰 행운을 사용하여 봄을 관리하 JPA 트랜잭션이 있습니다.지저분한 정보의 연결을 여는 진술,그 결과 세트,쓰기를 통해 복잡한 시도/catch/마지막으로 블록(도/catch 블록 에서 마지막으로 블록!)을 닫고 다시 그들만 사라지고,당신을 떠날 실제로 얻을 수 있습니다.I'd highly recommend 마이그레이션하는 종류의 솔루션입니다.

Java,문(지 않은 결과)연결을 커서 오라클도 있습니다.그것은 최고의를 닫는 리소스를 열으로 예상치 못한 문제가 발생할 수 있습에 관해서 JVM 및 시스템 리소스입니다.

또한 일부 JDBC 풀링 프레임워크에 수영장 명세서 및 연결므로 폐쇄되지 않을 수도 있습을 표시하지 않는다 해당 개체로에서 무료로 수영장,그리고 원인 성능 문제에 framework.

일반적으로,이 있는 경우 close()또는()메소드를 파괴 개체에 대한 이유가 있을것,그리고 그것을 무시하는 것은 그렇게 자기에게 위험을 초래한다는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top