DD异常,清理数据库资源:有干净的解决方案吗?
Posted
技术标签:
【中文标题】DD异常,清理数据库资源:有干净的解决方案吗?【英文标题】:DD anomaly, and cleaning up database resources: is there a clean solution? 【发布时间】:2012-05-31 22:22:23 【问题描述】:这是我们都写过的一段代码:
public CustomerTO getCustomerByCustDel(final String cust, final int del) 抛出 SQLException 最终 PreparedStatement 查询 = getFetchByCustDel(); 结果集记录=空; 尝试 query.setString(1, cust); query.setInt(2, del); 记录 = query.executeQuery(); 返回 this.getCustomer(records); 最后 如果(记录!= null) 记录.close(); 查询.close();如果您省略了“finally”块,那么您的数据库资源就会悬空,这显然是一个潜在的问题。但是,如果您按照我在此处所做的操作 - 在 **try** 块外将 ResultSet 设置为 null,然后在块内将其设置为所需的值 - PMD 会报告“DD 异常”。在文档中,DD异常描述如下:
DataflowAnomalyAnalysis:数据流分析跟踪本地定义、未定义和对数据流不同路径上变量的引用。从这些信息中可以发现各种问题。 [...] DD - 异常:重新定义了最近定义的变量。这是不祥之兆,但不一定是错误。
如果您在块外声明 ResultSet 而不设置值,则在执行 if (records != null) 测试时,您会得到“变量可能尚未初始化”错误。
现在,在我看来,我在这里的使用不是错误。但是有没有一种干净地重写不会触发 PMD 警告的方法?我不是特别想禁用 PMD 的 DataFlowAnomalyAnalysis 规则,因为识别 UR 和 DU 异常实际上很有用;但是这些 DD 异常让我怀疑我可以做得更好——而且,如果没有更好的方法来做这件事,它们就会变得混乱(我或许应该看看我是否可以重写 PMD 规则)
【问题讨论】:
【参考方案1】:我认为这更清楚:
PreparedStatement query = getFetchByCustDel();
try
query.setString(1, cust);
query.setInt(2, del);
ResultSet records = query.executeQuery();
try
return this.getCustomer(records);
finally
records.close();
finally
query.close();
另外,在您的版本中,如果 records.close() 抛出异常,查询不会关闭。
【讨论】:
【参考方案2】:我认为 DD 异常注释更多的是错误,而不是功能 还有就是你释放资源的方式有点不完整,比如
PreparedStatement pstmt = null;
Statement st = null;
try
...
catch (final Exception e)
...
finally
try
if (pstmt != null)
pstmt.close();
catch (final Exception e)
e.printStackTrace(System.err);
finally
try
if (st != null)
st.close();
catch (final Exception e)
e.printStackTrace(System.err);
而且这又不对了,因为你应该关闭这样的资源
PreparedStatement pstmt = null;
Throwable th = null;
try
...
catch (final Throwable e)
<something here>
th = e;
throw e;
finally
if (th == null)
pstmt.close();
else
try
if (pstmt != null)
pstmt.close();
catch (Throwable u)
【讨论】:
以上是关于DD异常,清理数据库资源:有干净的解决方案吗?的主要内容,如果未能解决你的问题,请参考以下文章
没有标记就不能清理网络爬虫吗?用正则表达式是否不能让它干净?