我遇到的问题是我的Java应用程序从数据库中导出了大量的clob,但是由于旧的clobs没有被释放,所以总是耗尽临时表空间.
一个简化的代码示例我是如何做到的:
public void getClobAndDoSomething (oracle.jdbc.OracleCallableStatement pLSQLCodeReturningClob) {
try (OracleCallableStatement statement = pLSQLCodeReturningClob) {
statment.registerOutParameter(1, Types.CLOB);
statement.execute();
oracle.sql.CLOB clob = statement.getCLOB(1);
clob.open(CLOB.MODE_READONLY);
Reader reader = clob.getCharacterStream();
BufferedReader bufferedReader = new BufferedReader(reader);
doSomethingWithClob(bufferedReader);
bufferedReader.close();
reader.close();
clob.close();
clob.freeTemporary();
} catch (SQLException e) {
if (e.getErrorCode() == 1652) {
//Server ran out of temporary tablespace
} else
handleException(e);
} catch (IOException e) {
handleException(e);
}
}
Run Code Online (Sandbox Code Playgroud)
如果在循环中调用此方法,它将总是在某个时刻耗尽临时表空间.
释放空间的唯一可靠方法是关闭连接并打开一个新连接(例如通过使用clob.getInternalConnection.close()),但这会降低应用程序的速度并使当前的多线程方法无法使用.
可悲的是,ojdbc上的oracle文档并没有真正有用,谷歌只发现文章告诉我使用free()lobs 的方法甚至没有由oracles临时clobs实现.
附加说明:
使用oracles APEXExport.class导出大型工作区时也会出现此问题.
驱动程序和系统细节: