java.sql.SQLException: ORA-01000: maximum open cursors exceeded;问题的解决方法

ORA-01000: maximum open cursors exceeded  
ORA-00604: error occurred at recursive SQL level 1  

ora-01000: maximum open cursors exceeded:表示已经达到一个进程打开的最大游标数。

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

一般来说,Java中createStatement和prepareStatement都应该要放在循环外面,而且使用了这些Statment后,及时关闭。最好是在执行了一次executeQuery、executeUpdate等之后,如果不需要使用结果集(ResultSet)的数据,就马上将Statment关闭。

对于出现ORA-01000错误这种情况,单纯的加大open_cursors并不是好办法,那只是治标不治本。实际上,代码中的隐患并没有解除.而且,绝大部分情况下,open_cursors只需要设置一个比较小的值,就足够使用了,除非有非常特别的要求。

2.解决方案:

1)从源头上解决方案(建议)

  检查代码,把涉及到打开链接的地方,用完之后,千万别忘记关掉。

session.doWork(new org.hibernate.jdbc.Work() {
	@Override
	public void execute(Connection connection) throws SQLException {
		CallableStatement cs = connection.prepareCall(prepareCallSql);
		cs.setString(1, params);
		cs.setClob(2, connection.createClob());
		cs.registerOutParameter(2, Types.CLOB);
		cs.execute();
		Reader reader = cs.getClob(2).getCharacterStream();
		try {
			resultBuffer.append(IOUtils.toString(reader));
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
                        /*force close io will ignores nulls and special case*/
			//IOUtils.closeQuietly(reader);
                        /*close connect*/
			if(cs != null) { try { cs.close();} catch(Exception e) { e.printStackTrace(); } }
		}
	}
});

2)临时解决方案(不建议)

  通过修改oracle系统参数:将OPEN_CURSORS 的值设置得足够大,以避免应用程序用尽所有打开的游标。应用程序不同,该值也不同。即便会话打开的游标数未达 OPEN_CURSORS 指定的数量(即设置的值高于实际需要的值), 也不会增加系统开销。 

 

补充:

IOUtils 简要说明(More refer to https://blog.csdn.net/woshiwxw765/article/details/7538872/)

该类为input/output操作提供了通用静态方法, 包括功能:

•closeQuietly——这些关闭一个流的方法将忽略nulls和例外的情况。

•toXxx /read-这些方法从一个流读取数据。

• write这些方法将数据写到一个流里。

copy——这些方法用于从一个流的所有的数据复制到另一个流。

•contentEquals——这些方法用于比较两个流的内容。

 

Refer to:https://www.cnblogs.com/qinjunli/p/4588089.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值