您的位置:首页 > 其它

ORA-01000: 超出打开游标的最大数(解决及原因)

2012-10-31 17:34 316 查看
clip_image001[4]

既然超出最大游标数, 为了第一间让程序恢复正常运行, 当然"脚疼治脚", 先把最大游标数调大:

(1). 以 DBA 登录 PL/SQL

(2). 打开 Command Window(注意不是 SQL Window)

clip_image002[4]

(3). 输入以下命令, 修改 oracle 最大游标数为 1000

1 SQL> alter system set open_cursors=1000 scope=both;

(4). 查看最大游标数是否已修改成功

1 SQL> show parameter open_cursors;

(5). 重启 tomcat(一定要有这一步, 否则修改不生效)

经过以上操作, 票据顺利上传上去了, 可是这样治标不治本, 万一以后来个1000张以上的票据要上传, 那不就又得改游标数了; 在代码里肯定是每处理一张票就打开一个游标的, 这样是错误的. 网上找了这个错误代码的相关说明, 在这里发现以下这段话

这样的错误很容易出现在Java代码中的主要原因是:Java代码在执行conn.createStatement()和 conn.prepareStatement()的时候,实际上都是相当与在数据库中打开了一个cursor。尤其是,如果你的 createStatement和prepareStatement是在一个循环里面的话,就会非常容易出现这个问题。因为游标一直在不停的打开,而且没有关闭。

在代码里看了一下, 果然是这样, 程序通过循环调用封装好的 executeSql 函数, 来对每张票进行 update, 而 executeSql 里每次都调用了 conn.prepareStatement(); 将其移出循环, 再改回原游标数, 再上传票据, 就不再报错了.

public static void executeSql(Connection conn, String sql, Object[] parValue) throws Exception{

PreparedStatement ps = null;

try {

LOGGER.info(sql);

ps = conn.prepareStatement(sql);

if (parValue != null){

String params = "";

for (int i = 0; i < parValue.length; i++){

if (i != 0){

params += ",";

}

ps.setObject(i+1, parValue[i]);

params += parValue[i];

}

LOGGER.info(params);

}

ps.execute();

} catch (SQLException e) {

e.printStackTrace();

throw new Exception();

} finally {

if (ps != null){

ps.close();

}

}

}

注: 原代码有进行 ps.close(); 的, 但是仍然无效, 是因为 connection 的 autocommit 设为 false 的原因? 还是因为 connection 是从连接池取的原因呢?

有一个问题说明 connection 与 prepareStatement 进行 close 的关系, 但这里只是说明了直接 close connection, 而没有说明直接 close prepareStatement.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐