最近因爲系統和業務重構須要,須要把線上1億數據遷移到新庫,因爲業務變動,新表老表結構有變化,無法直接用dba dump的方式,須要本身寫轉換程序遷移。今天在調試的時候,碰到一個蛋疼的問題,就是一開始查詢數據都正常,可是查詢幾條後日志就會報超時錯誤,具體日誌以下:java
No ManagedConnections available within configured blocking timeout ( 5000 [ms] ); - nested throwable: (javax.resource.ResourceException: No ManagedConnections available within configured blocking timeout ( 5000 [ms] ))
搜了下這個錯誤,各類說法比較多,可是感受都沒說到點上,找DBA看了下,DBA直接表示這個庫鏈接數一直吃緊,從這個錯誤看也是鏈接超時,原本覺得就這麼着了,可是調試了幾回都是一開始正常,後來報異常,就感受確定仍是代碼有問題致使鏈接數吃緊,後來仔細看了下代碼,發現是connection沒有關閉...應該說是沒有關閉全。把PrepareStatement和ResultSet關閉了,可是沒把最重要的Connection關閉掉...關閉了Connection就正常了。數據庫
網上幾個搜的結果太過於誤導人,因此就記錄一下,碰到這個錯誤,首先是確認本身代碼是否有相關connection沒關閉掉,基本都是沒關閉connection致使的,最後再確認數據庫鏈接數是否是真的吃緊。spa
以下代碼僅供參考:調試
1 try{ 2 conn = sourceDs.getConnection(); 3 ps = conn.prepareStatement(selectTcBizOrder); 4 rs = ps.executeQuery(); 5 if(rs.next()){ 6 result.put("auction_id", rs.getLong("auction_id")); 7 result.put("logistics_status", rs.getInt("logistics_status")); 8 result.put("attributes", rs.getString("attributes")); 9 return result; 10 }else{ 11 return null; 12 } 13 }catch(SQLException e){ 14 LogFactory.getTaskLog().error("[select tc_biz_order SQLException], bizOrderId="+bizOrderId, e); 15 return null; 16 }catch(Exception e){ 17 LogFactory.getTaskLog().error("[select tc_biz_order other Exception], bizOrderId="+bizOrderId, e); 18 return null; 19 }finally{ 20 if(rs != null){ 21 try{ 22 rs.close(); 23 }catch(SQLException e){ 24 LogFactory.getTaskLog().error("[close ResultSet SQLException], bizOrderId="+bizOrderId, e); 25 } 26 } 27 28 if(ps != null){ 29 try { 30 ps.close(); 31 } catch (SQLException e) { 32 LogFactory.getTaskLog().error("[close PreparedStatement SQLException], bizOrderId="+bizOrderId, e); 33 } 34 } 35 36 if(conn != null){ 37 try{ 38 conn.close(); 39 }catch(SQLException e){ 40 LogFactory.getTaskLog().error("[close Connection SQLException], bizOrderId="+bizOrderId, e); 41 } 42 } 43 }