JDBC连接泄漏

时间:2016-04-07 07:30:21

标签: java oracle jdbc memory-leaks connection

我目前在我的代码(Java,Struts)中面临连接泄漏问题。我已经关闭了所有结果集,预处理语句,可调用语句以及我的dao中所有方法的finally块中的连接。我仍然面临这个问题。另外的信息是,我使用StructDescriptor.createDescriptor来创建oracle对象。它会导致任何连接泄漏吗?请指教。

以下代码

         public boolean updatedDetails(Distribution distribution, String    appCode, Connection dbConnection) {
    boolean savedFlag = true;
    CallableStatement updateStoredProc = null;
    PreparedStatement pstmt1 = null;
    try {
        logger.debug("In DistributionDAO.updatedDistributionDetails");
        //PreparedStatement pstmt1 = null;
        ARRAY liArray = null;
        ARRAY conArray = null;
        ARRAY payArray = null;
    ArrayDescriptor licenseeArrDesc = ArrayDescriptor.createDescriptor(LICENSEE_TAB, dbConnection);
        ArrayDescriptor contractArrDesc = ArrayDescriptor.createDescriptor(DISTRIBUTION_CONTRACT_TAB, dbConnection);
        ArrayDescriptor paymentArrDesc = ArrayDescriptor.createDescriptor(DISTRIBUTION_PAYMENT_TAB, dbConnection);
        licenseeArray = new ARRAY(licenseeArrDesc, dbConnection, licenseeEleList.toArray());
            contractArray = new ARRAY(contractArrDesc, dbConnection, contractEleList.toArray());
            paymentArray = new ARRAY(paymentArrDesc, dbConnection, paymentEleList.toArray());           
            updateStoredProc = dbConnection.prepareCall("{CALL DIS_UPDATE_PROC(?,?,to_clob(?),?,?,?,?)}");
            updateStoredProc.setLong(1, distribution.getDistributionId());
            updateStoredProc.setString(2, distribution.getId());
            updateStoredProc.setString(3, distribution.getNotes());
            updateStoredProc.setString(4, distribution.getNotesUpdateFlag());
            updateStoredProc.setArray(5, liArray);
            updateStoredProc.setArray(6, conArray);
            updateStoredProc.setArray(7, payArray);
            String sql1="Update STORY set LAST_UPDATE_DATE_TIME= sysdate WHERE STORY_ID = ? ";
            pstmt1=dbConnection.prepareStatement(sql1);
            pstmt1.setLong(1,distribution.getStoryId());
            pstmt1.execute();
            List<Object> removedEleList = new ArrayList<Object>();
            removedEleList.add(createDeleteElementObject(removedEle, dbConnection));
            catch (SQLException sqle) {
        savedFlag = false;

    } catch (Exception e) {
        savedFlag = false;

    } finally {
        try {
            updateStoredProc.close();
            updateStoredProc = null;            
            pstmt1.close();
            pstmt1 = null;      
            dbConnection.close();
        } catch (SQLException e) {

        }
    }
    return savedFlag;
}




// Method createDeleteElementObject
private Object createDeleteElementObject(String removedEle,
        Connection connection) {

    StructDescriptor structDesc;
    STRUCT structObj = null;
    try {
        structDesc = StructDescriptor.createDescriptor(DISTRIBUTION_REMOVED_ELEMENT_OBJ, connection);
        if(removedEle != null) {
            String[] tmpArr = removedEle.split("\\|");
            if(tmpArr.length == 2) {
                Object[] obj = new Object[2];
                String eleType = tmpArr[0];
                long eleId = Integer.parseInt(tmpArr[1]);
                obj[0] = eleType.toUpperCase();
                obj[1] = eleId;
                structObj = new STRUCT(structDesc, connection, obj);
            }
        }
    } catch (ArrayIndexOutOfBoundsException e) {

    } catch (NumberFormatException e) {

    } catch (SQLException e) {

    }

    return structObj;
}     

2 个答案:

答案 0 :(得分:2)

您的代码的一些提示:

您将Connection变量传递到您的通话中,但在通话中关闭它 - 来电者是否知道这一事实?在代码中使用连接将是更清晰的将其关闭(调用方法负责)

异常意味着被捕获,而不是被忽略 - 您不会记录您的异常 - 您永远不会知道会发生什么。我打赌你的catch块中的一个简单e.printStackTrace()将显示有用的信息。

使用try-with-resource(请参阅this post

//Resources declared in try-with-resource will be closed automatically.
try(Connection con = getConnection();
    PreparedStatement ps = con.prepareStatement(sql)) {

    //Process Statement...

} catch(SQLException e) {
  e.printStackTrace();
}  

至少把每一个关闭放在单个try-catch中:

} finally {
    try {
        if(updateStoredProc != null) {
          updateStoredProc.close();   
        }         
    } catch (SQLException e) {
        e.printStackTrace();
    }
    try {
        if(pstmt1!= null) {
          pstmt1.close();   
        }         
    } catch (SQLException e) {
        e.printStackTrace();
    }
    try {
        if(dbConnection != null) {
          dbConnection.close();   
        }         
    } catch (SQLException e) {
        e.printStackTrace();
    }
  }

答案 1 :(得分:0)

以下是与简单JDBC交互时“减轻痛苦”的工具列表:

  1. Spring's JdbcTemplate
  2. jOOQ
  3. Apache DbUtils(我主要用于Servlet项目)
  4. JDBI
  5. sql2o
  6. persism

DBUtils示例:

try{ ..........  }
catch(Exception ex){   ........   }
finally{
   DbUtils.closeQuietly(dbConnection, pstmt1, updateStoredProc);
}