2

ApacheDBCP接続プーリングを使用して取得された接続オブジェクトを使用してCLOB列を更新しようとしています。

以前、これを使用して接続プールを実装しましたが、正常に機能していました。つまり、CLOBを更新できます。java.sql.SQLExceptionが発生したため、DBCPに切り替えました。ORA -01000:開いているカーソルの最大数を超えました。すべてのDAOの接続、resultSet、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()接続を渡してみましたが、無駄です。

また、ここでシャイニーが提案したことを試してみました。今回はデータを選択しているときにぶら下がっています。

Oracle 9iを使用していて、JDBC Oracle Driverのバージョンが10を超えています(申し訳ありませんが、現在正確なバージョンを思い出せませんでした)。

4

3 に答える 3

1

PreparedStatement.setClobの代わりにメソッドを使用してみましたsetObjectか?

于 2009-09-24T14:03:34.697 に答える
1

Oracle JDBC ドライバーでは、setClob(). エラーはスローされませんが、機能しません。この背後にある理由は、JDBCドライバー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 オブジェクトを取得する必要があります。それらのいずれかを自分で作成しようとしないでください。

于 2009-10-23T13:49:09.417 に答える
0

OTN には、Oracle JDBC での clob 処理に関するドキュメントがいくつかあり、役立つ場合があります。

于 2009-09-24T15:44:56.100 に答える