为什么数据库连接经常在两个位置关闭,一次是在使用后直接关闭,其次是在finally块中使用null检查以防止它们被关闭两次.使用finally块是不够的?在每种情况下都要执行finally块.
这是Apache-Tomcat JNDI数据源HOW-TO的官方示例.他们指出,在任何情况下都必须关闭连接.我想知道为什么使用finally-block是不够的,因为主try {} -block结束时的close-commands似乎是redundent.
Connection conn = null;
Statement stmt = null; // Or PreparedStatement if needed
ResultSet rs = null;
try
{
conn = ... get connection from connection pool ...
stmt = conn.createStatement("select ...");
rs = stmt.executeQuery();
... iterate through the result set ...
rs.close ();
rs = null;
stmt.close ();
stmt = null;
conn.close (); // Return to connection pool
conn = null; // Make sure we don't close it twice
}
catch (SQLException e)
{
... deal with errors ...
}
finally
{
// Always make sure result sets and statements are closed,
// and the connection is returned to the pool
if (rs != null)
{
try
{
rs.close ();
}
catch (SQLException ignore)
{
}
rs = null;
}
if (stmt != null)
{
try
{
stmt.close ();
}
catch (SQLException ignore)
{
}
stmt = null;
}
if (conn != null)
{
try
{
conn.close ();
}
catch (SQLException ignore)
{
}
conn = null;
}
}
Run Code Online (Sandbox Code Playgroud)
我想写得更短:
Connection conn = null;
Statement stmt = null; // Or PreparedStatement if needed
ResultSet rs = null;
try
{
conn = ... get connection from connection pool ...
stmt = conn.createStatement ("select ...");
rs = stmt.executeQuery();
... iterate through the result set ...
}
catch (SQLException e)
{
// ... deal with errors ...
}
finally
{
// Always make sure result sets and statements are closed,
// and the connection is returned to the pool
try
{
if (rs != null)
rs.close ();
if (stmt != null)
stmt.close ();
if (conn != null)
conn.close ();
}
catch (SQLException ignore)
{
}
}
Run Code Online (Sandbox Code Playgroud)
你有一个很好的问题 - 我也不理解"官方例子".最后块肯定够了.
然而,你的代码有更严重的缺陷,即如果rs.close()将抛出一个异常,你必须stmt和conn泄漏出来,你想也忽略例外默默.这是你不应该做的事情.从Java 7开始,使用try-with-resources构造是首选方法,但如果你不能去那里,至少分别处理每个可能的异常(rs,stmt,conn),这样它们就不会导致彼此泄漏.
例如,Apache commons DbUtils 只为此目的而使用closeQuietly(),因为它曾经是一种常见的场景.我个人会去像Spring JDBCTemplate那样在幕后做这种事情的地方.
编辑:Oracle 在此解释了try-with-resources .简而言之,你会这样做:
try (Connection conn = yourCodeToGetConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query)) {
while (rs.next()) {
String coffeeName = rs.getString("COF_NAME");
int supplierID = rs.getInt("SUP_ID");
float price = rs.getFloat("PRICE");
int sales = rs.getInt("SALES");
int total = rs.getInt("TOTAL");
System.out.println(coffeeName + ", " + supplierID + ", " +
price + ", " + sales + ", " + total);
}
} catch (SQLException ex) {
// log, report or raise
}
Run Code Online (Sandbox Code Playgroud)
try-statement自动处理conn,stmt并rs在所有情况下按顺序关闭(与您声明它们的相反顺序).您仍需要处理的可能异常.
| 归档时间: |
|
| 查看次数: |
4326 次 |
| 最近记录: |