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异常,清理数据库资源:有干净的解决方案吗?的主要内容,如果未能解决你的问题,请参考以下文章

没有标记就不能清理网络爬虫吗?用正则表达式是否不能让它干净?

异常进程终止时的资源清理

清理手机缓存每次都要花费很长时间,有啥办法可以快速清理吗?

怎么卸载mysql????如何清理干净?

求鲁大师优化与清理(鲁大师优化清理工具) V2.14.10.1123 绿色单文件版网盘资源

c盘怎么清理