Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java关闭连接和findbugs_Java_Database_Findbugs - Fatal编程技术网

Java关闭连接和findbugs

Java关闭连接和findbugs,java,database,findbugs,Java,Database,Findbugs,在我们的代码中,我们通常使用以下模式: Connection conn; try{ conn = getConnection(); //Do databasey stuff }catch(Exceptions that get thrown){ }finally{ try{ conn.close(); }catch(SQLException ex){ logger.error("Failed to cleanup database

在我们的代码中,我们通常使用以下模式:

Connection conn;
try{
    conn = getConnection();
    //Do databasey stuff
}catch(Exceptions that get thrown){
}finally{
    try{
        conn.close();
    }catch(SQLException ex){
        logger.error("Failed to cleanup database connection",ex);
    }
}
但是findbugs不喜欢这样。由于conn.close()可以引发异常,因此连接不能保证关闭。 是findbugs太迂腐了,还是有更好的方法关闭数据库连接

编辑:
添加了删除的试扣。是的,有更好的方法

创建在try/catch中包装结束的静态方法:

public class DatabaseUtils
{
    public static void close(Connection c)
    {
        try
        {
            if (c != null)
            {
                c.close();
            }
        }
        catch (SQLException e)
        {
            // print or log stack trace
        }
    }

    // same for Statement and ResultSet
}

没有更好的方法,但如果您想确保捕获所有内容,请将您的模式修改为:

Connection conn;
try{
    conn = getConnection();
    //Do databasey stuff
}catch(Exceptions that get thrown){
}finally{
    try {
       conn.close();
    }
    catch  (SQLException se) {
       log.error("database problems...");
       // do more stuff if you need to
    }
}

已经有一个实用程序实现了@duffymo提到的功能:来自Apache

  • DbUtils.close(ResultSet)
  • DbUtils.close(语句)
  • DbUtils.close(连接)
显示所有可用的方法


更新

下面是一个例子:

import org.apache.commons.dbutils;


Connection conn;
try{
    conn = getConnection();
    //Do databasey stuff
} catch(Exception e){
    //throw a glorious exception....
} finally{
    DbUtils.closeQuietly(conn); //This hides the SQLException thrown by conn.close();
    //or 
    //DbUtils.close(conn);
}

更新:正如ArtB所建议的,如果您最终关闭了资源和连接,而findBugs是一个唠叨者,那么您可以添加以下注释(在方法的顶部)


是的,你应该将你的收盘价封装在试牌中,但有一种更聪明的方法

try {
    Connection c = getConnection();
    try {
        //do stuff
    } finally {
        c.close();
    }
} catch (SQLException e) {
    //Catch exceptions
}

您真正想做的是将“精英绅士”的答案与
@edu.umd.cs.findbugs.annotations.SuppressWarnings(“OBL\u未满足的义务”)
注释结合起来。FindBugs似乎只有在您以以下方式使用完整的收尾方法时才会感到高兴(顺便说一句,这是这样做的首选顺序):

这是非常冗长的,如果出于对腕管的热爱,您可能不想这样做,因此您应该使用
DBUtils.closequity()
方法(或者创建您自己的调用)。但是,FindBugs不认为这(即使用库或您自己的方法)是正确关闭资源并向您发出警告。在这种情况下,这显然是一个错误。因此,必须确保它是您得到的唯一警告,然后禁用该方法的特定警告

@edu.umd.cs.findbugs.annotations.SuppressWarnings( "OBL_UNSATISFIED_OBLIGATION" )
public void doStuff( final Connection connection ){
    try{
        //Do databasey stuff
    }catch( SqlException e ){
        //throw a glorious exception....
    }finally{
        DbUtils.closeQuietly( resultSet  );
        DbUtils.closeQuietly( statement  );
        DbUtils.closeQuietly( connection );
}

通过这种方式,您只需几行代码就可以清理资源,避免出现FindBugs警告。

您可以通过使用Spring JDBCTemplate之类的工具来避免整个问题,它为您正确封装了所有打开/关闭逻辑,简化了代码,使其更清晰、更易于阅读(而且更可能是正确的)

例如,将表中的一些列读入键值对列表(是的,很难看,但很容易理解):

List resultList=jdbcTemplate.query(查询,
新的行映射器(){
@凌驾
公共地图地图行(结果集rs,
int rownum)抛出SQLException{
Map row=newhashmap();
int-colIndex=0;
row.put(CONTENTID_键,rs.getInt(++colIndex));
put(CONTENTTYPEID_键,rs.getInt(++colIndex));
row.put(DESCRIPTION_KEY,rs.getString(++colIndex));
put(CODE_KEY,rs.getString(++colIndex));
返回行;
}
});


有关异常处理,请参见

conn.close在catch中,已更新问题以添加此内容。@Stephen:总有更好的方法;只是乍一看并不总是很明显。-1所以把试扣放回去。为了简洁而编辑它应该是非实质性的。您的代码验证程序是否存在未捕获异常问题,或者连接不能保证关闭?是否添加了try-catch。Findbugs在上述方面存在问题,因为如果在conn.close()期间引发异常,连接(可能)将保持打开状态。javac应该会抱怨该代码。如果你做了一些愚蠢的事情,比如说,用
null
分配
conn
,那么你就有了一个潜在的NPE。@Jim我建议你看看我的答案,因为我认为它比你当前选择的答案更好。使用资源进行尝试可以解决所有问题并解决问题;)这当然更整洁,因为无论在何处使用连接,都会减少重复捕捉。但是我相信findbugs仍然不会高兴,因为关闭时的异常将意味着它将保持打开状态。
//打印或日志堆栈跟踪
否,您应该抛出异常(可能是
SQLException
)。您不一定要抛出异常。虽然无法关闭连接很烦人,但它不一定会导致事务回滚之类的事情。@Tom Hawtin-不,这个方法的全部目的是防止异常发生。你误解了这个问题。@duffymo,令人惊讶的是为什么会有没有解释的否决票。我认为实际上应该禁止。FindBugs似乎仍然会抱怨如果你使用DBUtils来关闭连接。@ArtB,你是安静地关闭连接还是使用DBUtil简单关闭(捕获异常)?我使用的是
DBUtils.closeQuiety()
。答案是添加注释
@edu.umd.cs.findbugs.annotations.SuppressWarnings(“OBL\u未满足的义务”)
。我希望这能得到投票,让人们看到它,而不是仅仅停留在“更多评论”链接中。也许我应该加上它作为一个单独的答案?这不是“更聪明的(原文如此)”;如果抛出异常,连接将泄漏。如果我错了,请纠正我,但如果在内部try块中抛出异常,finally块仍将运行。“连接将泄漏”的唯一方法是关闭语句本身抛出异常。
...
}finally{
    try{ 
       resultSet.close();
    }catch( SqlException e ){
       //log error
    }finally{
       try{
          statement.close();
       }catch( SqlException e ){
          //log error
       }finally{
          try{
              connection.close();
          }catch( SqlException e ){
              //log error
          }
       }
    }
}
@edu.umd.cs.findbugs.annotations.SuppressWarnings( "OBL_UNSATISFIED_OBLIGATION" )
public void doStuff( final Connection connection ){
    try{
        //Do databasey stuff
    }catch( SqlException e ){
        //throw a glorious exception....
    }finally{
        DbUtils.closeQuietly( resultSet  );
        DbUtils.closeQuietly( statement  );
        DbUtils.closeQuietly( connection );
}
        List<Map<String, Object>> resultList = jdbcTemplate.query(query,
                new RowMapper<Map<String, Object>>() {
                    @Override
                    public Map<String, Object> mapRow(ResultSet rs,
                            int rownum) throws SQLException {
                        Map<String, Object> row = new HashMap<String, Object>();
                        int colIndex = 0;
                        row.put(CONTENTID_KEY, rs.getInt(++colIndex));
                        row.put(CONTENTTYPEID_KEY, rs.getInt(++colIndex));
                        row.put(DESCRIPTION_KEY, rs.getString(++colIndex));
                        row.put(CODE_KEY, rs.getString(++colIndex));
                        return row;
                    }
                });