我在Java应用程序中使用下面的oracle select查询
select a.xmlrecord.getClobVal() xmlrecord from tablename where ID like 'ABC%' order by ID
执行选择查询后,我使用以下代码检索输出并关闭结果集并在finally块处进行连接
Reader reader = new BufferedReader(orset.getCharacterStream("xmlrecord"));
突然我遇到以下错误,如下所示
java.sql.SQLException: ORA-04068: existing state of packages has been discarded
ORA-04030: out of process memory when trying to allocate 107112 bytes
我已经与DBA核对过,他坚持认为该错误是由于 JDBC代码正在xmltype上调用getclobVal(),并且没有检查它是否是临时lob,也没有代码显式地释放它。
在方法结束时,是否需要关闭Clob对象的任何内容。请注意,我仅在查询中使用clobval(),在其他地方没有使用,而且我没有在代码中创建任何Clob / lob对象。
请提供您对上述错误的输入。
答案 0 :(得分:1)
getClobVal()是一个SQL函数,它将实例化服务器上的LOB对象,并且 返回适当的LOB定位器到Java客户端。
即使它最初是用语句持续时间创建的,将定位器返回给客户端的操作也会使LOB变成会话持续时间对象。
您需要更改Java代码以执行类似...
Clob xmlrecord = orset.getClob("xmlrecord"));
Reader reader = new BufferedReader(xmlrecord.getCharacterStream());
然后您可以执行...
xmlrecord.free();
根据所使用的版本,Oracle JDBC可能会为您释放对象而无需干预,但是无论如何您都应该始终对此进行编码。如果该对象已被释放,则为空操作,否则它将关闭,如果为临时LOB,则将调用freeTemporary()释放服务器上的资源。
12.2.0.1中的错误修复23205826,尤其是18.1中的错误修复26335028,可能会有所帮助。
答案 1 :(得分:0)
您可以指定使用的JDBC版本吗?您还在temp lob上使用free()方法吗?
答案 2 :(得分:0)
您说要提取100,000行,每行3 MB?那就是300 GB的结果集? kes。由于这不是PL / SQL,因此没有什么免费的。我的猜测是Oracle只是在构建一个太大的结果集,而您超出了PGA。
如果仅检索一行,这行吗?您可能需要分批获取结果。