我有一个像下面的代码部分:
try (UnitOfWork unitOfWork = datasource.getConnection()) {
ResultSet resultset = untiOfWork.getStatement().getResultSet();
unitOfWork.queueToClose(resultSet);
...
}
UnitOfWork是AutoClosable。因此,UnitOfWork
close()
方法内部就是这样。
@Overide
public void close() {
for (AutoClosable closable : queueToClose) {
closable.close();
}
connection.close();
}
现在,FindBug抱怨ResultSet没有被关闭。这是误报吗?这是一个糟糕的模式吗?
答案 0 :(得分:2)
除了Alexey Romanov'发布在您的UnitOfWork.close实现中可能存在泄漏,如果这些关闭调用中的任何一个抛出异常,则表明您的连接未关闭。
@Override
public void close() throws Exception {
Exception first = null;
try (AutoCloseable requiredForJdk8 = this.connection) {
for (AutoCloseable closable : this.queueToClose) {
try {
closable.close();
} catch (Exception e) {
if (first == null) {
first = e;
} else {
if (first != e) {
first.addSuppressed(e);
}
}
}
}
if (first != null){
throw first;
}
}
}
答案 1 :(得分:1)
在ResultSet
将被关闭的意义上是误报,但FindBugs无法知道这一点。
这也是一个糟糕的模式:如果您在获得queueToClose
后忘记致电ResultSet
,会发生什么? UnitOfWork.getStatement()
在返回之前是否将语句添加到queueToClose
?
最好是
try (UnitOfWork unitOfWork = datasource.getConnection();
Statement statement = unitOfWork.getStatement();
ResultSet resultset = statement.getResultSet()) {
...
}