关于JDBC的资源释放问题

zhaowanlun 2004-07-22 11:37:06
高手们,请看下面的代码, 请问资源释放是否正确,但为什么数据库中,总有没
释放的cursor呢。(我用的是ORACLE数据库)


ArrayList alTaskExecList;
PreparedStatement psExecInfoStmt;

……
……

public synchronized int writeTaskExecInfo(){

if(alTaskExecList.isEmpty()==true){
return -1;
}
String sCmdLine="";
String sSql="";
TaskExecInfo mTaskExecRec = new TaskExecInfo();

try{
int iCount = alTaskExecList.size();
int i;
for(i=0;i<iCount;iCount--){
mTaskExecRec = (TaskExecInfo)alTaskExecList.get(i);
sSql="INSERT INTO tad_taskexecinfo"+
" (task_id,cmdline,status,start_time) VALUE
("+mTaskExecRec.iTaskId+",?,"+mTaskExecRec.iStatus+
",'"+mTaskExecRec.sStartTime+"')";

psExecInfoStmt = mCon.prepareStatement(sSql);
psExecInfoStmt.setString(1,sCmdLine);
log.write("=====psExecInfoStmt.setString ? = "+sCmdLine+"\n");
psExecInfoStmt.executeUpdate();

alTaskExecList.remove(i);//从列表中删除成功的语句
log.write("DBProxy::writeTaskExecInfo insert sql:"+sSql+" success\n");
log.write("cmdline:"+sCmdLine+"\n");
}

}catch(Exception e){
log.write("DBProxy::writeTaskExecInfo failed,Sql:"+sSql+e+"\n");
log.write("cmdline:"+sCmdLine+"\n");
e.printStackTrace();
return -1;
}
finally
{
Scheduler.log.write("========== in finally =========="+"\n");
if( psExecInfoStmt != null )
try{
psExecInfoStmt.close();
log.write("==== close"+"\n");
}catch(SQLException se)
{}
}
return 0;
}



运行较长一段时间后,会出现异常:

java.sql.SQLException: ORA-01000: maximum open cursors exceeded
ORA-06512: at "NMOSDB.TR_TAD_TASKEXECINFO_SERIAL_I", line 4
ORA-04088: error during execution of trigger 'NMOSDB.TR_TAD_TASKEXECINFO_SERIAL_I'

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:579)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1894)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1094)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2132)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2015)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2877)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:608)
at DBProxy.writeTaskExecInfo(DBProxy.java:344)
at DBProxy.run(DBProxy.java:59)
at java.lang.Thread.run(Thread.java:536)



在数据库中,用select * from v$OPEN_CURSOR; 察看确实有许多没有释放的cursor.
...全文
222 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
gong1 2004-07-22
  • 打赏
  • 举报
回复
没有看到Connection ResultSet close()
^_^
仔细看看。。。。
^_^
happyegg 2004-07-22
  • 打赏
  • 举报
回复
这一段代码是没问题的。
数据库的操作需要关闭的有:
Connection -- 一般最后才关闭
Statement -- 每次使用都要关闭
ResultSet -- 每次使用都要关闭
你看看其他的程序里面有没有是用到上面三个而没有close的地方
朋友别哭 2004-07-22
  • 打赏
  • 举报
回复
up
ll42002 2004-07-22
  • 打赏
  • 举报
回复
你写的数据库操作程序在循环里面,那么每次循环都要创建一个psExecInfoStmt实例,而你即使在程序最后close(),也只是释放了一个psExecInfoStmt实例,那么当然就会有很多没有释放了。
在这种情况下,建议你使用JDBC的批处理,就不会有那种问题发生了。
blasterboy 2004-07-22
  • 打赏
  • 举报
回复
建议你看看连接池什么的,那个挺好的:)具体我也不太会:)
blasterboy 2004-07-22
  • 打赏
  • 举报
回复
你开开了连接没有关闭
还有就是看看ORACLE设置的cursor是不是太小了:)

67,516

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧