简体   繁体   English

JDBC 连接泄漏

[英]JDBC connection leak

I am currently facing connection leak problem in my code (Java , Struts).我目前在我的代码(Java、Struts)中面临连接泄漏问题。 I have closed all the result sets, prepared statements, callable statements and the connection in the finally blocks of all the methods in my dao.我已经关闭了我的 dao 中所有方法的 finally 块中的所有结果集、准备好的语句、可调用语句和连接。 still I face the issue.Additional information is , I am using StructDescriptor.createDescriptor for creating oracle objects.我仍然面临这个问题。附加信息是,我正在使用 StructDescriptor.createDescriptor 来创建 oracle 对象。 Will it cause any connection leaks?它会导致任何连接泄漏吗? Please advise.请指教。

Code below下面的代码

         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;
}     

Some hints on your code:关于您的代码的一些提示:

You pass a Connection variable into your call but close it inside your call - is the caller aware of that fact?您将Connection变量传递到您的呼叫中,但在您的呼叫中关闭它 - 呼叫者是否知道这一事实? It would be cleaner to get the connection inside your code or return it unclosed (calling method is responsible)在代码中获取连接将其返回未关闭会更干净(调用方法负责)

Exceptions are meant to be caught, not ignored - you don't log your exception - you'll never know what happens.异常应该被捕获,而不是被忽略——你不会记录你的异常——你永远不会知道会发生什么。 I bet a simple e.printStackTrace() in your catch blocks will reveal helpful information.我敢打赌,catch 块中的简单e.printStackTrace()会显示有用的信息。

Use try-with-resource (see this post )使用try-with-resource (请参阅此帖子

//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();
}  

At the very least put every close inside single try-catch:至少将每个关闭放在单个 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();
    }
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM