【问题标题】:unable to update CLOB using DBCP connection无法使用 DBCP 连接更新 CLOB
【发布时间】:2010-12-01 02:01:45
【问题描述】:

我正在尝试使用使用 Apache DBCP 连接池检索的连接对象来更新 clob 列。

之前,我使用this 实现了连接池,它工作正常,即能够更新 CLOB。我切换到 DBCP 因为我得到 java.sql.SQLException: ORA-01000: maximum open cursors exceeded。我检查了所有 DAO 中的连接、结果集、preparedStatement 对象。所有 finally 块都关闭了这些游标。仍然面临这个错误,因此决定切换到 DBCP。

但是,当我尝试使用此 DBCP 连接更新 CLOB 时,应用程序只是在 pstmt.executeUpdate() 处挂起。

Connection conn = null;
        PreparedStatement pstmt = null;
        CLOB clob = null;
        String q = "UPDATE REPORT_TABLE SET RPT_FILE = ? WHERE RPT_SEQ_NUM = ?";
        ...
            conn = DBConnection.getConnection();
            pstmt = conn.prepareStatement(q);
            clob = getCLOB(xmlReport, conn);
            pstmt.setObject(1, clob);
            pstmt.setString(2, reportSeqNo);

            if (pstmt.executeUpdate() == 1) {
                logger.logError("Report has been successfully UPDATED");
            }
        ...

getCLOB() 方法在哪里:

private CLOB getCLOB(String xmlData, Connection conn) throws SQLException{
    CLOB tempClob = null;
    try{
        // If the temporary CLOB has not yet been created, create new
        tempClob = CLOB.createTemporary(conn, true, CLOB.DURATION_SESSION);

        // Open the temporary CLOB in readwrite mode to enable writing
        tempClob.open(CLOB.MODE_READWRITE);
        // Get the output stream to write
        Writer tempClobWriter = tempClob.getCharacterOutputStream();
        // Write the data into the temporary CLOB
        tempClobWriter.write(xmlData);

        // Flush and close the stream
        tempClobWriter.flush();
        tempClobWriter.close();

        // Close the temporary CLOB
        tempClob.close();
    } catch(SQLException sqlexp){
        tempClob.freeTemporary();
        sqlexp.printStackTrace();
    } catch(Exception exp){
        exp.printStackTrace();
        tempClob.freeTemporary();
        exp.printStackTrace();
    }
    return tempClob;
}

我也尝试过传递((DelegatingConnection) conn).getInnermostDelegate() 连接,但没有用。

另外,我尝试了Shiny 建议的here。这次它在我选择数据时挂起。

我使用的是 Oracle 9i,并且 JDBC Oracle 驱动程序版本高于 10(抱歉,现在不记得确切的版本了)。

【问题讨论】:

  • 能否展示一下您的 getCLOB 方法(以及“xmlReport”是什么数据类型?)?

标签: java oracle jdbc clob apache-commons-dbcp


【解决方案1】:

使用 Oracle JDBC 驱动程序,您不能使用setClob()。它不会抛出错误,但它也不会工作。这背后的原因是 JDBC 驱动程序将尝试读取您的 Clob 流 inside executeUpdate()。所以你必须在更新之前打开流,运行更新然后关闭流之后

因此,我总是使用select RPT_FILE ... for update,然后:

    ResultSet rs = null;
    try
    {
        rs = stmt.executeQuery ();
        rs.next ();

        Clob clob = rs.getClob (1);
        clob.truncate (0);
        clob.setString (1, data);
    }
    finally
    {
        rs = DBUtil.close (rs);
    }

您可以将setString() 替换为将CLOB 作为流读取/写入的方法。这总是有效并且不会泄漏游标(由于 Oracle 的 JDBC 驱动程序中的错误)。

但关键始终是相同的:您必须从 Oracle 获取一个 CLOB 对象。永远不要尝试自己创建其中之一。

【讨论】:

    【解决方案2】:

    您是否尝试过使用PreparedStatement.setClob 方法而不是setObject

    【讨论】:

      【解决方案3】:

      OTN 有一些documentation on clob handling in Oracle JDBC 可能会有所帮助。

      【讨论】:

        猜你喜欢
        • 2019-10-18
        • 2021-09-08
        • 2019-03-03
        • 2014-01-09
        • 2013-01-06
        • 2011-11-17
        • 2015-01-09
        • 2012-05-13
        相关资源
        最近更新 更多