最近由于系统和业务重构需要,需要把线上1亿数据迁移到新库,由于业务变更,新表老表结构有变化,没法直接用dba dump的方式,需要自己写转换程序迁移。今天在调试的时候,碰到一个蛋疼的问题,就是一开始查询数据都正常,但是查询几条后日志就会报超时错误,具体日志如下:
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导致的,最后再确认数据库连接数是不是真的吃紧。
如下代码仅供参考:
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 }