Jdbc DD异常和清理数据库资源:是否有一个干净的解决方案?

Jdbc DD异常和清理数据库资源:是否有一个干净的解决方案?,jdbc,findbugs,pmd,dataflow,Jdbc,Findbugs,Pmd,Dataflow,下面是我们都写过的一段代码: public CustomerTO getCustomerByCustDel(final String cust, final int del) throws SQLException { final PreparedStatement query = getFetchByCustDel(); ResultSet records = null; try { query.s

下面是我们都写过的一段代码:

public CustomerTO getCustomerByCustDel(final String cust, final int del) throws SQLException { final PreparedStatement query = getFetchByCustDel(); ResultSet records = null; try { query.setString(1, cust); query.setInt(2, del); records = query.executeQuery(); return this.getCustomer(records); } finally { if (records != null) { records.close(); } query.close(); } } 公共客户到GetCustomerByCustomDel(最终字符串cust,最终整数del) 抛出SQLException{ final PreparedStatement query=getFetchByCustDel(); 结果集记录=null; 试一试{ query.setString(1,cust); query.setInt(2,del); records=query.executeQuery(); 返回此.getCustomer(记录); }最后{ if(记录!=null){ 记录。关闭(); } query.close(); } } 如果省略“finally”块,那么数据库资源就会悬而未决,这显然是一个潜在的问题。但是,如果您执行了我在这里所做的操作-在**try**块外将ResultSet设置为null,然后在块内将其设置为所需的值-PMD报告“DD异常”。在文件中,DD异常描述如下:

数据流异常分析:数据流分析跟踪数据流上不同路径上的局部定义、未定义和对变量的引用。从这些信息中可以发现各种问题。[…]DD-异常:重新定义了最近定义的变量。这是不祥的,但不一定是一个错误。 如果在块外声明ResultSet而不设置值,则在执行If(records!=null)测试时会正确地得到一个“variable not have initialized”(变量可能尚未初始化)错误


现在,在我看来,我在这里的使用不是一个错误。但是有没有一种干净的重写方法不会触发PMD警告?我并不特别想禁用PMD的DataflowAnomalyananalysis规则,因为识别UR和DU异常实际上是有用的;但是这些DD异常让我怀疑我可以做得更好——如果没有更好的方法,它们就相当于混乱(我也许应该看看是否可以重写PMD规则)

我认为这更清楚:

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()引发异常,则查询不会关闭。

我认为DD异常注释更像是一个bug,而不是一个功能
此外,例如,您释放资源的方式有点不完整

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) {
        }
    }
}
PreparedStatement pstmt=null;
可丢弃th=null;
试一试{
...
}捕获(最终可丢弃e){
th=e;
投掷e;
}最后{
如果(th==null){
pstmt.close();
}否则{
试一试{
如果(pstmt!=null){
pstmt.close();
}
}捕获(可丢弃的u){
}
}
}