2014-10-15 4 views
1

데이터베이스에 연결하기 위해 "postgresql-9.3-1102.jdbc3.jar"를 사용하고 있습니다. 한 가지 예외가있을 때 예 : null 값 하나, 예외를 잡으려면 여러 가지 방법을 사용할 수 있습니다.Postgres 예외 및 java

시도 { ............} 캐치 (PSQLException SERS) { ......... }

또는

시도 {.......} 캐치 (예외 : SQLException 자체) {.......}

또는

시도 { .......} catch (예 ception) { ........

내 목표는 흥미로운 경우에 특정 SQLState를 잡는 것입니다.

예를 들어 한 필드의 유효하지 않은 NULL 값을 catch하려는 경우 Postgress는 "23502"SQLState 값을 반환하지만 오류 코드가 상속되기 때문에 이전의 "catch"중 하나에서이를 수행 할 수 없습니다. 그것을 확인할 수 없습니다. 내가 SQLSTATE 어떤 아이디어

감사를 검사 할 이전 "캐치"에서

는 내가 ".getmessage"을 가질 수 있지만, 이것은 나에게 도움이되지 않습니다.

답변

5

캐치 SQLExceptoin 및보고 비교 필요.

catch (SQLException ex) { 
    final String ss = ex.getSQLState(); 
    //... blah blah ... 
} 

SQLState 세부 정보는 PostgreSQL error codes을 참조하십시오. (대부분의 주 카테고리와 코드는 DB에서 표준이지만 모든 DB가 동일한 방식으로 구현되고 동시에 포기하는 것은 아니며 대부분의 DB에는 DB 관련 추가 기능이 있습니다).

SQLState를 기반으로 예외를 catch 할 수있는 방법이 없습니다. 불행히도, 그것을 잡아야 만합니다. 그리고 그것이 당신이 원하는 것을 포장하고 다시 던지면 안됩니다. (포장하지 않고 그냥 다시 타지 않으면 원래의 스택을 잃어 버리게됩니다.)

JDBC 4에는 JDBC 드라이버가 해당 서브 클래스를 throw하는 경우에만 잡을 수있는 SQLException과 같은 서브 클래스가 있습니다 (SQLNonTransientException). PgJDBC를 쓰는 시점에서 PgJDBC는이를 지원하지 않으며 항상 단순히 SQLException을 던집니다. 따라서 잡으려고하면 아무것도 잡을 수 없습니다. (패치는 환영합니다!).


현실 세계에서는 다양한 오류 조건에 관심이 많으며이를 기반으로 여러 가지 작업을 수행하려고합니다. 막연하게 같은

뭔가 안된 서면 - 인 - 더 - 창

} catch (SQLException ex) { 
    final String ss = ex.getSQLState(); 
    if (ss.equals("40001") || ss.equals("40P01")) {  
    /* It is a serialization failure or a deadlock abort. Retry the tx. */ 
    retry_transaction = true; 
    } else if (ss.startsWith("08") || ss.startsWith("53")) { 
    /* It is a connection error or resource limit. Reconnect and retry. */ 
    try { 
     conn.close(); 
    } catch (SQLException ex) { 
     logger.log("Error closing suspected bad connection after SQLState " + ss, ex); 
    } 
    conn = null; /* App knows to reconnect if it sees a null connection */ 
    retry_transaction = true; 
    } else { 
    throw new MyAppException(ex); 
    } 
} 

... 앱이 거래의 기록을이 널 연결을 보는 경우 다시 연결을 알고, 그리고 유지 그것은 단지 시도 했으므로 교착 상태 또는 직렬화 실패가 발생하면 성공할 때까지 루프에서 다시 시도 할 수 있습니다.

현실적으로 재시도 속도 제한을 추가하는 것보다 더 똑똑 할 것입니다. 이것은 단순한 예일뿐입니다.


은 자세한 내용 조성을위한 테스트 후 PSQLException에 예외를 던져, 또는 처음에 PSQLException로 잡을 수있어. 당신에게 상세한 필드가 ServerErrorMessage을 제공

ex.getServerErrorMessage() 

: 그 다음에 세부 사항을 얻을.

+0

@ 그레이그 회신 해 주셔서 대단히 감사하지만 내 경우에는 ex.getSQLState() "null"반환합니다 그래서 당신을 말할 깜빡 SQLState를 사용하지 마십시오. 왜 이런 일이 일어나는 지 이해할 수 없습니다. Netbeans를 IDE로 사용하고 디버그에서 se.Cause.Inherit 아래에서 SQLstate = 23502를 볼 수 있도록 도와 주도록 도와주세요. SQLState –

+0

@EliasElias 일괄 처리 오류입니다. 일반적인 오류가 아닌 특정 오류를 언급하는 경우 질문에 스택 추적을 표시해야합니다. 일괄 처리 인 경우 중첩 예외를 얻으려면 ['getNextException'] (http://docs.oracle.com/javase/7/docs/api/java/sql/SQLException.html#getNextException%28%29)해야합니다. . –

+0

@CraigRinger 나는 똑같은 문제에 직면하고 있으며, 배치에 있지 않다. 원인으로'null'을 얻었고'getNextException()'도'null'을 반환합니다. – Pere

0

SQL 상태를

DatabaseMetaData dmd = connection.getMetaData(); 
int type = dmd.getSQLStateType(); 

http://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html#getMetaData%28%29 http://docs.oracle.com/javase/7/docs/api/java/sql/DatabaseMetaData.html#sqlStateSQL

전체 예를 얻을 수있는 연결을 사용 : 그것은 당신이 무엇을의 경우 다음 SQLException.getSQLState()를 사용

Connection conn = null; 
try 
{ 
    String url = "jdbc:postgresql://localhost/yourdb?user=test&password=secret"; 
    conn = DriverManager.getConnection(url); 
    // Some sql query or stuff 
} 
catch (Exception e) 
{ 
    if (conn != null) 
    { 
     DatabaseMetaData dmd = conn.getMetaData(); 
     int type = dmd.getSQLStateType(); 
     // Do something with this state 
    } 
} 
+0

왜'e.getSQLState() '대신에 그렇게 할 수 있습니까? –

+0

그래, 당신의 방법은 더 나은 찾고 있지만 내 경우에도 NullPointerException catch했습니다 – ToYonos