首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未释放CLOB的临时表空间

未释放CLOB的临时表空间
EN

Stack Overflow用户
提问于 2015-08-14 05:31:29
回答 1查看 3.5K关注 0票数 6

我的问题是我的正在从数据库导出大量的clobs,但是由于旧的clobs没有释放,所以总是耗尽临时表空间。

下面是一个简化的代码示例:

代码语言:javascript
复制
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);
    }
}

如果在循环中调用此方法,则始终会在某一时刻耗尽临时表空间。

释放空间的唯一可靠方法是关闭连接并打开一个新的连接(例如,通过使用clob.getInternalConnection.close()),但这会减慢应用程序的速度,并使当前的多线程方法不可用。

遗憾的是,ojdbc上的oracle文档并没有真正的帮助,谷歌只找到了一些文章,告诉我如何使用lobs的free()方法,这甚至没有由oracles临时clobs实现。

附加说明

在使用oracles APEXExport.class导出大工作区时也会出现此问题。

驱动程序和系统细节:

  • 操作系统: Windows 7专业x64
  • 1.8.0_45 :64位
  • ojdbc: 6(是否有更具体的版本?)
  • 数据库: Oracle数据库11g企业版发行版11.2.0.1.0 -64位生产

如果您有APEX-应用程序,则测试代码:

代码语言:javascript
复制
java.sql.Connection con = getConnection();
String gStmtGetAppClob = "begin ? := wwv_flow_utilities.export_application_to_clob(?, ?, ?, ?); end;";
int appId = 100;

while (true) {
    OracleCallableStatement exportApplicationToClob = (OracleCallableStatement) con.prepareCall(gStmtGetAppClob);
    exportApplicationToClob.setString(3, "Y"); //Public reports
    exportApplicationToClob.setString(4, "N"); //Saved reports
    exportApplicationToClob.setString(5, "N"); //Interactive report notifications
    exportApplicationToClob.setBigDecimal(2, new BigDecimal(appId));

    getClobAndDoSomething(exportApplicationToClob);
    try {
        Thread.sleep(50);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        break;
    }
}
con.close();

更新:

经过更多的测试后,我发现clobs在某个时候得到了释放,而没有关闭连接。所以看起来free()实际上是一个lazyFree()。但这需要超过一分钟的时间。

我也可以把CLOB转换成Clob,不知道我之前做错了什么。如果使用Clob,问题将保持不变。

EN

回答 1

Stack Overflow用户

发布于 2015-08-14 08:49:40

在pl/sql世界中,这将通过临时CLOB处理,并在循环中重用它。

假设您使用的是java.sql.CLOB.,它似乎没有createTemporary CLOB选项,但oracle.sql.CLOB有。它还具有freeTemporary()方法来清除临时空间。

01/appdev.112/e13995/oracle/sql/CLOB.html

调用例程可以创建临时CLOB,并将其作为参数(例如p_clob)传递给此方法。每次都将查询的返回值分配给p_clob,而不是创建新的CLOB (例如CLOB = statement.getCLOB)。

现在时间不够,但稍后会编辑详细的代码。如果你能与上面的工作,那么很好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32002900

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档