繁体   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