我目前在我的代码(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;
}
答案 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交互时“减轻痛苦”的工具列表:
DBUtils示例:
try{ .......... }
catch(Exception ex){ ........ }
finally{
DbUtils.closeQuietly(dbConnection, pstmt1, updateStoredProc);
}