簡體   English   中英

JDBC 4的java.sql.Clob.free()方法和向后兼容性

[英]JDBC 4's java.sql.Clob.free() method and backwards compatibility

我正在調查一個有趣的性能問題,在經常使用的資源上沒有調用java.sql.Clob.free() Clob上的這個方法是在Java 6 / JDBC 4中引入的,所以很可能這實際上是從JDBC 3升級到JDBC 4時引入的回歸。

這是Oracle JDBC驅動程序中的已知問題嗎? 可以說,之前, Clobs以某種方式神奇地釋放了自己,而使用JDBC 4,它們必須手動釋放? 或者是否有可用於與JDBC 3保持兼容的驅動程序設置?

注意,當然,這同樣適用於Blob

我們的應用程序必須確保在oracle.sql.CLOB(使用toJdbc()獲取java.sql.Clob)上使用Oracle 11g和'ojdbc6.jar'顯式調用java.sql.Clob.free()(規范 - 版本) MANIFEST.MF中的'4.0'和實現 - 版本'11 .2.0.3.0'。 否則應用程序遭受大量內存泄漏。

在這里查找了Oracle Database的Oracle供應商JDBC驅動程序(ojdbc6.jar)
我在這里找到了demo.zip文件
我解壓縮它,並為clob和blob尋找源代碼。
有一個文件TemporaryLobJDBC40.java
在那里,有一個示例,其中創建了temp clob和blob,然后填充了一些數據,然后通過預准備語句(參數化INSERT)插入到表中。
然后,執行,關閉語句,釋放temp clob和blob並提交事務。

然后,作者循環遍歷表的行,創建永久blob / clobs,並為它們分配從getClob(),getBlob()返回的對象,並將內容轉儲到流中。

永久性的斑點永遠不會被釋放。 我假設在每次迭代后,當對象超出范圍時,垃圾收集器會自動釋放這些對象。

在最后一次迭代之后,最后兩個Blob / Clob對象沒有被顯式釋放,但是被垃圾回收器(當它決定啟動時)隱式清理它們的范圍以最后一次迭代結束。 (之后 })

就個人而言,我會明確地進行清理工作,但要對每個人進行清理。 這個演示表明你可以
無論如何都要這樣做。

這是代碼(TemporaryLobJDBC40.java):

/*
 * This sample shows how to create
 * a temporary BLOB and CLOB, write
 * some data to them and then insert
 * them into a table. This makes a 
 * permanent copy in the table. The 
 * temp lobs are still available for
 * further use if desired until the
 * transaction is committed.
 * When fetched from the table, the
 * lobs are no longer temporary.
 *
 * This version uses the new 
 * JDBC 4.0 factory methods in 
 * java.sql.Connection and the
 * free methods in java.sql.Blob and Clob
 *
 * Testing for temporary status still 
 * requires Oracle specfiic APIs in 
 * oracle.sql.BLOB and oracle.sql.CLOB.
 *
 * It needs jdk6 or later version and ojdbc6.jar
 */

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Blob;
import java.sql.Clob;


class TemporaryLobJDBC40
{
  public static void main (String args [])
    throws Exception
  {
    Connection conn = DemoConnectionFactory.getHRConnection( args );
    LobExample.createSchemaObjects( conn );
    Blob tempBlob = conn.createBlob();
    Clob tempClob = conn.createClob();

    System.out.println ("tempBlob.isTemporary()="+
                        ((oracle.sql.BLOB)tempBlob).isTemporary());
    System.out.println ("tempClob.isTemporary()="+
                        ((oracle.sql.CLOB)tempClob).isTemporary());
    LobExample.fill(tempBlob, 100L);
    LobExample.fill(tempClob, 100L);

    String insertSql = "insert into jdbc_demo_lob_table values ( ?, ?, ? )";
    PreparedStatement pstmt = conn.prepareStatement( insertSql );
    pstmt.setString( 1, "one" );
    pstmt.setBlob( 2, tempBlob );
    pstmt.setClob( 3, tempClob );
    pstmt.execute();
    pstmt.close();
    tempBlob.free();
    tempClob.free();
    conn.commit();

    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery( "select b, c from jdbc_demo_lob_table" );
    while( rs.next() )
    {
      Blob permanentBlob = rs.getBlob(1);
      Clob permanentClob = rs.getClob(2);
      System.out.println ("permanentBlob.isTemporary()="+
                          ((oracle.sql.BLOB)permanentBlob).isTemporary());
      System.out.println ("permanentClob.isTemporary()="+
                          ((oracle.sql.CLOB)permanentClob).isTemporary());
      LobExample.dump(permanentBlob);
      LobExample.dump(permanentClob);
    }
    rs.close();
    stmt.close();
    conn.close();
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM