为什么JDBC连接需要在finally块中关闭?

时间:2015-09-28 06:29:10

标签: java jdbc

Connection conn = null;
Statement stmt = null; 
ResultSet rs = null;
try
{
    conn = geting the connection object ( using DriverManager.getConnection() method or using connection pool)
    stmt = conn.createStatement ("select ...");
   // some other logic here
}
catch (SQLException e)
{
    // handling the exceptions
}
finally
{

}

我的问题是在以下情况下关闭连接对象时会出现什么问题。

  1. 假设没有发生异常,在尝试阻止,它会自动关闭连接对象。

    try {
         // same above code 
         stmt.close();
         conn.close();
    } catch(Exception ex) {
        // handling the exceptions
    } finally {
    
    }
    
  2. 如果发生了一些异常,那么它将转到 catch block ,它会自动关闭连接对象。

    try {
         // same above code 
    
    } catch(Exception ex) {
        // handling the exceptions
        stmt.close();
        conn.close();
    } finally {
    
    }
    
  3. finally块中关闭连接对象。

    try {
         // same above code 
    
    } catch(Exception ex) {
        // handling the exceptions
    
    } finally {
        stmt.close();
        conn.close();
    } 
    
  4. 使用close()方法关闭连接对象和使用close()关闭池化连接之间的区别。
  5. 注意:请不要说在finally块中关闭连接对象是好的。我知道那个。如果我在try块中保持紧密连接,那么catch块是否有任何问题请解释。

8 个答案:

答案 0 :(得分:13)

建议关闭finally区块中的连接,因为如果您有多个catch区块(应该如此:永远不会抓住通用{{1} })您不必重写结束语句。

Exception阻止总是finally后执行,无论发生什么。因此,如果您获得try或其他一些您无法处理的例外情况,则可以使用NullPointerException数据块确保您的资源正常关闭。

但如果您使用的是java 7,我建议使用try-with-resources

答案 1 :(得分:7)

由于数据库占用的资源越来越多,因此建议您在处理完成后关闭连接,无论是否成功。

您说在conn.close()中添加try,如果您的查询在没有任何异常的情况下运行,这很好,如果您的查询有任何问题,则不会关闭连接。所以总是建议在finally块中关闭你的连接,无论是否发生异常,都会执行。此外,如果您尝试将结束语句放在catch块中并尝试处理多个异常,则需要重复您的代码,这是不推荐的。

答案 2 :(得分:2)

始终执行finally块,包括以下情况:

  • 试块的正常终止。

  • 在某些catch中处理异常时异常终止try-block。

  • 异常传播给调用者时异常终止。

  • 块中间的return语句:

    try {
       if(something) return false; // finally is executed here as well
       ...
    } finally { ... }
    
  • 如果整个try-catch在循环中,则为breakcontinue语句:

    while(condition) {
        try {
            if(something) continue; // finally is executed here
            else if(somethingElse) break; // finally is executed here
            ...
        }
        finally {
        }
    }
    

因此无论你如何退出try块,finally都将被执行,你不应该关心检查每一种可能的退出方式。这真的很方便。

答案 3 :(得分:2)

finally块始终执行:

try{
 // code logic
 }catch(SQLException ex){
 // catch exception
 }finally{
   if (dbConnection != null){
            dbConnection.close();
       }
 }

答案 4 :(得分:1)

  • 如果您未处理的异常被抛出,会发生什么? (一世 希望你没有抓住Throwable ...)
    • 如果从try块内部返回会发生什么?
    • 如果catch块抛出异常会怎样?

finally块确保无论你退出该块(模式显式地中止整个过程的几种方式),它都会被执行。这对于确定性清理资源非常重要。

注意:另外,为防止应用程序资源泄漏,我们必须关闭连接.. !!

感谢。!!

答案 5 :(得分:1)

你可以在try或catch块中关闭连接,但是会告诉你为什么在finally块中关闭连接是好的

假设您已尝试使用catch块,如下所示:

try{
stmt1..
stmt2..
conn.close
}
catch(exception e){
}

现在假设exception is raised by stm1,那么您的连接将保持打开状态。

现在考虑你正在关闭catch块中的连接.. what if no exception raised then control will never come in catch block ..这里连接仍然是开放的..我希望我能够清除你们中的一些疑问。

答案 6 :(得分:1)

答案是'我们必须在使用后关闭连接。'但实际问题是为什么我们必须在使用后关闭连接?

1。)当我们创建与远程数据库服务器的连接时,可以说是MySQL服务器,它还会为您保持连接打开。由于数据库服务器端还存在允许连接数量的限制/配置。如果我们不从我们的终端关闭连接,它将保持打开状态,在数据库服务器端将超过一小段允许的连接后,我们将无法与该数据库建立进一步的连接。

2。)数据库服务器端的自动释放连接时间设置。

如果我们没有从我们的结束关闭连接,并且我们在一段时间内没有执行任何查询(因为我认为MySql中的默认时间设置是28800秒。意味着8小时。虽然我们可以更改它。)它会自动从服务器端释放连接。

重要!当您的jdbc Connection对象在数据库服务器端真正发布并且您认为它仍然连接时会发生什么情况,因为您从未断开/关闭它并且您正在尝试执行使用语句查询该连接。 非常关键

这就是为什么我们必须始终关闭连接并在连接的连接对象上执行语句。

答案 7 :(得分:1)

最好使用try-with-resources语句。

什么是资源试用?

在Java中,try-with-resources语句是一个声明一个或多个资源的try语句。资源是一个在完成程序后必须关闭的对象。 try-with-resources语句确保在语句执行结束时关闭每个资源。

示例

try (Connection con = DriverManager.getConnection(myConnectionURL);
         PreparedStatement ps = createPreparedStatement(con, userId); 
         ResultSet rs = ps.executeQuery()) {

         // process the resultset here, all resources will be cleaned up

    } catch (SQLException e) {
        e.printStackTrace();
    }

在上面的示例中,Connection,PreparedStatement和ResultSet都在try块的末尾自动关闭。