4

バイナリ データを含む古い DB からのエクスポートをまとめてみたところ、ユーティリティ メソッドの 1 つで例外に遭遇しました。

java.lang.AbstractMethodError: net.sourceforge.jtds.jdbc.BlobImpl.free()

コードベースを確認したところ、ユーティリティ メソッドは今まで使用されていなかったことがわかりました。基本的には次のようになっています。

public BinaryHolder getBinary(final int columnIndex) throws SQLException {
    Blob blob = null;
    try {
        blob = resultSet.getBlob(columnIndex);
        final BinaryHolder binary = BinaryHolderUtil.create(blob);
        return binary;
    } finally {
        if (blob != null)
            blob.free();
    }
}

BinaryHolder は、バイナリ データを保持する単なるラッパーです (質問する前に、コードは finally 句に到達するまで正常に実行されます - BinaryHolderUtil.create(blob) はblob を解放しようとしません)。

さらに調査したところ、ブロブにアクセスする他のすべての場所で、ブロブは getBlob() を使用して取得され、まったく解放されていないことがわかりました (Javadoc によると、結果セットが閉じられると自動的に破棄されます)。

今すぐ質問: blobを手動で free() する必要があります (結局のところ、ResultSet は blob にアクセスするだけでなく保持される可能性があります)。それを実装していないドライバー?

(例外からまだ明らかでない場合は、JTDS1.25でSQL-Serverを使用しています)

4

1 に答える 1

7

これBlob.free()は JDBC 4.0 / Java 6 で導入されました。そのため、JDBC 3.0 以前の JDBC ドライバーを使用している可能性が高くなります。

ほとんどの (JDBC) リソースと同様に、それらをできるだけ早く閉じることには利点があります (たとえば、GC はそれをより早く収集でき、データベース リソースは解放されます)。ResultSetこれが、ステートメントを閉じる (またはステートメントを再度実行する) ときに、 が閉じているにもかかわらず、 をStatement閉じることができる理由でもありますConnection

したがって、 aを解放する必要Blobはありませんが、一般的には、作業が終わったら解放することをお勧めします。

ところで: JTDS は JDBC 3.0 のみです。Microsoft 自体の Microsoft SQL Server JDBC ドライバーを使用することをお勧めします。

于 2012-08-06T14:42:23.150 に答える