我在java应用程序中使用下面的oracle select查询。
select a.xmlrecord.getClobVal() xmlrecord from tablename where ID like 'ABC%' order by ID
执行select查询后,我将使用以下代码检索输出&关闭结果集和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
我已经和我的数据库管理员核实过了,他坚持说这个错误是由于JDBC代码正在对xmltype调用getclobVal(),并且没有检查它是否是临时lob,也没有代码显式地释放它。
对于方法末尾的Clob对象,有什么我们需要关闭的吗?请注意,我只是在我的查询中使用了clobval(),没有在其他地方使用,我也没有在代码中创建任何Clob/lob对象。
请提供您对上述错误的输入。
发布于 2018-12-10 10:50:34
getClobVal()是一个SQL函数,它将在服务器上实例化一个LOB对象,并将适当的LOB定位器返回给客户端。
即使LOB最初是使用语句持续时间创建的,将定位器返回给客户端的操作也会将LOB转换为会话持续时间对象。
您需要更改Java代码以执行以下操作:
Clob xmlrecord = orset.getClob("xmlrecord"));
Reader reader = new BufferedReader(xmlrecord.getCharacterStream());
然后你可以执行..。
xmlrecord.free();
根据您正在使用的版本,Oracle JDBC可能会为您释放对象,而无需干预,但无论如何,您都应该对此进行编码。如果对象已经被释放,那么它就是一个no-op,否则它将被关闭,如果是临时LOB,将调用freeTemporary()来释放服务器上的资源。
12.2.0.1中错误修复23205826,特别是18.1中的错误修复26335028可能会有所帮助。
发布于 2018-12-04 23:24:44
您能指定您正在使用的JDBC版本吗?另外,您是否在temp lob上使用free()方法?
发布于 2018-12-05 03:58:04
您说您正在提取100,000行,每行有3MB?这就是300 GB的结果集?啊呀。因为这不是PL/SQL,所以没有什么可以免费的。我的猜测是,Oracle正在构造一个太大的结果集,而您正在超出您的PGA。
如果只检索一行,这是否有效?您可能需要分批获取结果。
https://stackoverflow.com/questions/53612619
复制