Утечка соединения JDBC

В настоящее время я сталкиваюсь с проблемой утечки соединения в моем коде (Java, Struts). Я закрыл все наборы результатов, подготовленные операторы, вызываемые операторы и соединение в блоках finally всех методов в моем дао. Тем не менее я сталкиваюсь с проблемой. Дополнительная информация: я использую StructDescriptor.createDescriptor для создания объектов оракула. Не приведет ли это к утечке соединения? Пожалуйста, порекомендуйте.

Код ниже

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

person lal1990    schedule 07.04.2016    source источник
comment
А где твой код?   -  person Branislav Lazic    schedule 07.04.2016
comment
Я добавил код в edit.   -  person lal1990    schedule 07.04.2016
comment
Я настоятельно рекомендую вам переключиться на try-with-resources. То, как вы закрыли ресурсы в своем коде, может привести к утечке. Подумайте, что произойдет, если updateStoredProc.close() или pstmt1.close() вызовет исключение.   -  person Mark Rotteveel    schedule 07.04.2016
comment
Благодарю за ваш ответ. Не могли бы вы объяснить больше? Я не понимаю, что означает попытка с ресурсами.   -  person lal1990    schedule 07.04.2016
comment
См. утверждение попытки использования ресурсов.   -  person Mark Rotteveel    schedule 08.04.2016


Ответы (1)


Несколько советов по вашему коду:

Вы передаете переменную Connection в свой вызов, но закрываете ее внутри своего вызова - знает ли вызывающий об этом факте? Было бы чище получить соединение внутри вашего кода или вернуть его незакрытым (отвечает вызывающий метод)

Исключения должны быть перехвачены, а не проигнорированы — вы не регистрируете свое исключение — вы никогда не узнаете, что происходит. Бьюсь об заклад, простой e.printStackTrace() в ваших блоках выдаст полезную информацию.

Используйте 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();
}  

По крайней мере, поместите каждое закрытие внутри одного 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();
    }
  }
person Jan    schedule 07.04.2016
comment
Спасибо за ваш ответ, Ян, я попытался закрыть операторы и соединения вторым методом. Тем не менее я получаю проблему утечки соединения. После использования метода количество раз, объявленное в моем максимальном пуле standalone.xml, я не получаю ошибки управляемых исключений. - person lal1990; 08.04.2016
comment
Вы видите какие-либо исключения в своем журнале? - person Jan; 08.04.2016
comment
О, и вы вызываете множество методов оттуда, передавая соединение в качестве параметра. Их тоже нужно проверить (поделитесь кодом?) - person Jan; 08.04.2016
comment
Да... Я передаю соединение в качестве параметра и для других методов. Код, которым я уже поделился в своем исходном посте. Пожалуйста, обратитесь к нему. - person lal1990; 08.04.2016