4

只是将包含二进制数据的旧数据库的导出组合在一起,我偶然发现了我们的一个实用程序方法中的一个异常:

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)。

进一步调查我发现,在我们访问 Blob 的其他任何地方,blob 只是使用 getBlob() 获得的,根本没有释放(Javadoc 说当结果集关闭时它将自动处理)。

现在的问题:是否应该手动释放 blob(毕竟 ResultSet 的保存时间可能不仅仅是访问 blob),如果是,如何以一种即使使用没有实现它的驱动程序?

(我们正在使用带有 JTDS1.25 的 SQL-Server,如果这在异常中还不是很明显的话)

4

1 回答 1

7

是在 JDBC 4.0 / Java 6 中引入的Blob.free()。所以您很可能使用的是 JDBC 3.0 或更早版本的 JDBC 驱动程序。

与大多数(JDBC)资源一样,尽快关闭它们有其优势(例如,GC 可以更早地收集它,释放数据库资源等)。这也是为什么ResultSet即使在关闭语句(或再次执行语句)时关闭 a 也可以关闭它的原因,就像在关闭 aStatement时即使它关闭也可以关闭 a 一样Connection

所以 aBlob不需要被释放,但一般来说,当你完成它时释放它是一个好主意。

BTW:JTDS 只是 JDBC 3.0,你最好使用微软自己的 Microsoft SQL Server JDBC 驱动。

于 2012-08-06T14:42:23.150 回答