2009-09-24 2 views
2

Я пытаюсь обновить столбец clob, используя объект соединения, который извлекается с помощью пула соединений Apache DBCP.не удалось обновить CLOB с помощью соединения DBCP

Раньше я реализовал пул соединений с использованием this, и он отлично работал, я могу обновить CLOB. Я переключился на DBCP, потому что получал java.sql.SQLException: ORA-01000: максимальные открытые курсоры превышены. Я проверил соединения, resultSet, подготовил объектыStatement во всех DAO. Все блоки , наконец, блокируют эти курсоры. Все еще сталкиваюсь с этой ошибкой и поэтому решил переключиться на DBCP.

Но, когда я пытаюсь обновить CLOB, с этим соединением DBCP, приложение просто зависает на 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 и версию драйвера Oracle JDBC выше 10 (извините, не смог вспомнить точную версию сейчас).

+0

Не могли бы вы показать свой метод getCLOB (и какой тип данных «xmlReport»?)? – jsight

ответ

1

С драйвером Oracle JDBC вы не можете использовать setClob(). Он не будет вызывать ошибку, но это также не сработает. Причина этого в том, что драйвер JDBC попытается прочитать ваш поток Clob внутри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 в виде потока. Это всегда работает и не пропускает курсоры (из-за ошибок в драйвере JDBC от Oracle).

Но ключ всегда один и тот же: вы должны получить объект CLOB от Oracle. Никогда не пытайтесь создать один из них самостоятельно.

1

Вы использовали метод PreparedStatement.setClob вместо setObject?

Смежные вопросы