2013-01-18 21 views
0

我試圖做一個JDBC連接池組件,但遇到了問題。即:如何檢測java.sql.SQLException的錯誤狀態。 據說國家應該遵循SQL2003公約和XOPEN SQL公約JDK文件。但是我找不到任何有關這兩個約定的文件。有人可以爲我提供嗎?如何檢測SQ​​LException的SQL錯誤狀態

我想知道每個國家代表什麼,所以我可以決定何時完全關閉連接或重新連接。

我已經提到BoneCP的源代碼。下面是一個零件時SQLException的發生將被actived:

ImmutableSet<String> sqlStateDBFailureCodes = ImmutableSet.of("08001", "08007", "08S01", "57P01", "HY000"); 
    String state = e.getSQLState(); 
     ConnectionState connectionState = this.getConnectionHook() != null ? this.getConnectionHook().onMarkPossiblyBroken(this, state, e) : ConnectionState.NOP; 
     if (state == null){ // safety; 
      state = "08999"; 
     } 

     if (((sqlStateDBFailureCodes.contains(state) || connectionState.equals(ConnectionState.TERMINATE_ALL_CONNECTIONS)) && this.pool != null) && this.pool.getDbIsDown().compareAndSet(false, true)){ 
      logger.error("Database access problem. Killing off all remaining connections in the connection pool. SQL State = " + state); 
      this.pool.connectionStrategy.terminateAllConnections(); 
      this.pool.poisonAndRepopulatePartitions(); 
     } 
char firstChar = state.charAt(0); 
     if (connectionState.equals(ConnectionState.CONNECTION_POSSIBLY_BROKEN) || state.equals("40001") || 
       state.startsWith("08") || (firstChar >= '5' && firstChar <='9') /*|| (firstChar >='I' && firstChar <= 'Z')*/){ 
      this.possiblyBroken = true; 
     } 

     // Notify anyone who's interested 
     if (this.possiblyBroken && (this.getConnectionHook() != null)){ 
      this.possiblyBroken = this.getConnectionHook().onConnectionException(this, state, e); 
     } 

根據這些代碼,boneCP認爲它作爲一個數據庫服務器崩潰時的SQLException的狀態等於一體的「08001」,「08007」,「 08S01「,」57P01「,」HY000「。

但是爲什麼這些國家代表什麼?

+0

任何特殊功能或理由發展,而不是使用任何堅固的連接池庫? – Scorpion

+0

只是一種有趣的獲得我的技能提升。 –

回答

5

前兩個字符在SQL92 specification的「Table_23-SQLSTATE_class_and_subclass_values」中指定。

下面是相關的摘錄:

00 success completion 
01 warning 
02 no data 
07 dynamic SQL error 
08 connection exception 
0A feature not supported 
21 cardinality violation 
22 data exception 
23 integrity constraint violation 
24 invalid cursor state 
25 invalid transaction state 
26 invalid SQL statement name 
27 triggered data change violation 
28 invalid authorization specification 
2A direct SQL syntax error or access rule violation 
2B dependent privilege descriptors still exist 
2C invalid character set name 
2D invalid transaction termination 
2E invalid connection name 
33 invalid SQL descriptor name 
34 invalid cursor name 
35 invalid condition number 
37 dynamic SQL syntax error or access rule violation 
3C ambiguous cursor name 
3D invalid catalog name 
3F invalid schema name 
40 transaction rollback 
42 syntax error or access rule violation 
44 with check option violation 
HZ remote database access 

其餘字符是DB依賴於供應商。所以通常建議只執行startsWith()檢查。

+0

請注意,此列表並不是最新的(SQL:2011列出了更多的sqlstate類)並且不完整,因爲它僅列出基礎SQL狀態類,但不包括附加書中的那些類(CLI,PSM,MED,OLB ,JRT,XML),儘管我相信這還不是SQL:92。 –

2

SQL標準(ISO/IEC-9075),特別是書2基礎定義的SQL狀態。它們是一個2個字符的類值,後跟一個3個字符的子類值。

以數字'0','1','2','3'或'4'之一或簡單的拉丁大寫字母'A','B '','C','D','E','F','G'或'H'僅在ISO/IEC 9075或任何其他國際標準中定義的條件下返回。 [...]與這些類別相關的子類別值也是以這些13個字符中的一個開頭的,僅在ISO/IEC 9075或某些其他國際標準中定義的條件下返回。 [...]與以數字「5」,「6」,「7」,「8」或「9」之一開頭的類或與簡單拉丁大寫字母「I」 ,'J','K','L','M','N','O','P','Q','R','S','T','U',' V','W','X','Y'或'Z'是爲實現定義的條件保留的,並被稱爲實現定義的子類。

以數字'5','6','7','8'或'9'之一或簡單拉丁大寫字母'I','J'之一開始的類值, K,L,M,N,O,P,Q,R,S,T,U,V,W ','X','Y'或'Z'是爲實現定義的異常條件保留的,被稱爲實現定義的類。除'000'外的所有子類值(這意味着沒有子類)與這些類關聯,都保留給實現定義的條件,並稱爲實現定義的子類。

(從SQL:2011書2)

這些標準類(和標準定義的子類)在書2(基礎)被列出,3(CLI),4(PSM),9( MED),10(OLB),13(JRT)和14(XML)。它還列出是否有異常,警告,成功完成條件或無數據完成條件(並非所有SQL狀態都是錯誤!)

例如,在你的問題中列出的SQLSTATE是:

  • 08001:類:連接異常,子類:SQL客戶端不能建立SQL連接
  • 08007:類:連接異常,子類:事務分辨率未知
  • 08S01:類:連接異常,子類:以S開頭,所以是實現定義的子類(它在ODBC中定義爲通信鏈接失敗)
  • 57P0157P01:類:以5開始,所以是實現定義類,它似乎是用於ADMIN的PostgreSQL sqlstate SHUTDOWN
  • HY000:class:CLI特定的條件(在第3冊CLI中定義),子類:(無子類)

HY000是一個非常通用的錯誤一些數據庫或驅動程序將返回它不具有特定的SQLSTATE任何錯誤,所以它通常被視爲是致命的。我將BoneCP的行爲視爲將整個連接池關閉的原因有點矯枉過正,因爲HY000也可能導致相對良性的錯誤。其他sqlstates通常表示連接到數據庫(08001,08S01)或數據庫不可用(57P01)或數據庫本身存在問題(08007)時出現問題。