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/JDBC:发生异常时关闭数据库连接的最佳设计模式_Java_Database_Oracle_Jdbc - Fatal编程技术网

Java/JDBC:发生异常时关闭数据库连接的最佳设计模式

Java/JDBC:发生异常时关闭数据库连接的最佳设计模式,java,database,oracle,jdbc,Java,Database,Oracle,Jdbc,我是Java新手(我正在使用Java6)。我的所有Java POJO和servlet都使用了下面的设计模式,通过GlassFish 3.1.2 web服务器访问Oracle 11G数据库 当所有可用进程(或会话,不确定区别是什么)都被消耗时,我会遇到间歇性数据库错误(ORA-12519),这让我觉得应用程序没有释放这些进程 看看下面的设计模式,是否有更好的方法确保在发生异常时释放到数据库的JDBC连接?例如,如果(conn!=null)conn.close(),我是否也应该放置if捕捉块内的代码

我是Java新手(我正在使用Java6)。我的所有Java POJO和servlet都使用了下面的设计模式,通过GlassFish 3.1.2 web服务器访问Oracle 11G数据库

当所有可用进程(或会话,不确定区别是什么)都被消耗时,我会遇到间歇性数据库错误(ORA-12519),这让我觉得应用程序没有释放这些进程

看看下面的设计模式,是否有更好的方法确保在发生异常时释放到数据库的JDBC连接?例如,如果(conn!=null)conn.close(),我是否也应该放置
if捕捉块内的代码?或者,有更好的设计模式吗?提前感谢您的任何意见/提示

public String MyFunction() throws Exception {     

    Connection conn;
    CallableStatement cs;

  try {

      Context context = new InitialContext();
      DataSource ds = (DataSource)context.lookup("jdbc/MyPool");
      conn = ds.getConnection();        

      cs = conn.prepareCall( "{call my_sproc (?)}" );

      cs.registerOutParameter(1, Types.VARCHAR);

      cs.execute();

      String outParam = cs.getString(1); 

      if ( conn != null )  // close connection
         conn.close();

  } catch (Exception e) {
      outParam = "an error occurred";
  }
    return outparam;
}
始终使用块释放资源

当try块退出时,finally块始终执行。这确保即使发生意外异常,也会执行finally块

在这一行,
conn
不能为空。在Java 6之前,最流行的模式是:

Connection conn = null;
try {
   // initialize connection
   // use connection 
} catch {
  // handle exception
} finally {
  if (conn != null) {
     try { conn.close(); } catch (Exception e) { /* handle close exception, quite usually ignore */ } 
     }
}
使用Java7这将减少其构造的麻烦。上面的代码可以更改为更短的代码

try (Connection conn  = createConnection()) {
    // use connection 
} catch {
    // handle exception
}
// close is not required to be called explicitly

JavaSE7支持资源试用功能。这将为您生成最终结果

finally块将关闭try中分配的资源。就像你在c中使用关键字一样#

但是,用户正在使用JavaSE6。。。请参见其他用户的选项:)


重要提示:使用的语句也应该关闭。

我更喜欢另一种更优雅的方式,而不是:

} finally {
  if (conn != null) {
     try {
         conn.close();
     } catch (Exception e) {
         /* handle close exception, quite usually ignore */
     } 
  }
}

您可以使用DbUtils.closequilley:

谢谢Kazekage,如果连接尚未打开或其他原因,finally块中的
conn.close()
代码行是否会出错?如果是这样,我不应该在finally块中使用上面的
If(conn!=null)
语句吗?如果您怀疑
conn.close()
将再次给出错误,请用
try catch finally
环绕该语句。@ggkmath yes您需要测试
conn!=空
;如果
ds.getConnection()
引发异常,则可以为null。无论您是否怀疑,都需要将
close()
放入
try/catch/finally
;否则,该方法必须将其包含在其
throws
子句中,这是不好的。感谢这个变量,当您说“直到Java 6”时,您的意思是“直到并包括Java 6”(这就是我正在使用的)?我想是的。另外,当您说“通常被忽略”时,您是否仅指finally块中的
try…catch
(即
if(conn!=null)conn.close();
始终存在,对吗?)?为什么人们在关闭连接时通常忽略处理finally块中的异常?是的,
connection.close()
中的异常通常会被忽略,或者最多会被记录,但不会以任何其他方式处理:)我不知道为什么;我从来没有见过close抛出异常。我只是想说清楚,因为不管发生什么最终都会执行,所以我不需要关闭try块内的连接,对吗?我可以在代码中的finally块中关闭一次连接。是吗?是的,正如我在模板中所显示的,连接通常只在最后关闭。我没有阅读,但用户变量也谈到了使用资源进行尝试。我将在1分钟内确认这一点,但我猜您需要关闭语句。Doesn似乎不是通用的。你看,我错了。apidocs for不表示关闭
连接
会关闭其
语句
;但请注意,关闭
结果集需要关闭。JDBC规范规定,当连接关闭时,语句将关闭(JDBC 4.1规范第9.4.4.1节)。另外,
Connection.close()
的JavaDoc声明“立即释放此连接对象的数据库和JDBC资源”JDBC资源是从连接(即语句)创建的任何对象。请注意,关闭结果集和语句也是一种好的做法。这里有一个有用的链接(请参阅Stefan Schweizer在链接中的回复,以了解良好的设计模式):
try (Connection conn  = createConnection()) {
    // use connection 
} catch {
    // handle exception
}
// close is not required to be called explicitly
} finally {
  if (conn != null) {
     try {
         conn.close();
     } catch (Exception e) {
         /* handle close exception, quite usually ignore */
     } 
  }
}