在 Java 中关闭数据库连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2225221/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Closing Database Connections in Java
提问by onaclov2000
I am getting a little confused, I was reading the below from http://en.wikipedia.org/wiki/Java_Database_Connectivity
我有点困惑,我正在从http://en.wikipedia.org/wiki/Java_Database_Connectivity阅读以下内容
Connection conn = DriverManager.getConnection(
"jdbc:somejdbcvendor:other data needed by some jdbc vendor",
"myLogin",
"myPassword" );
Statement stmt = conn.createStatement();
try {
stmt.executeUpdate( "INSERT INTO MyTable( name ) VALUES ( 'my name' ) " );
} finally {
//It's important to close the statement when you are done with it
stmt.close();
}
Do you not need to close the conn Connection? What is really happening if the conn.close() doesn't occur?
不需要关闭conn连接吗?如果 conn.close() 不发生,真正发生了什么?
I have a private web app I'm maintaining that doesn't currently close either form, but is the important one really the stmt one, the conn one, or both?
我有一个我正在维护的私人网络应用程序,目前没有关闭任何一种形式,但重要的一个真的是 stmt 一个,conn 一个,还是两者兼而有之?
The site keeps going down intermittently but the server keeps saying it's a database connection issue, my suspicion is that it's not being closed, but I don't know which if any to close.
该站点不断断断续续地关闭,但服务器一直说这是一个数据库连接问题,我怀疑它没有被关闭,但我不知道要关闭哪个。
采纳答案by Pascal Thivent
When you are done with using your Connection
, you need to explicitly close it by calling its close()
method in order to release any other database resources (cursors, handles, etc) the connection may be holding on to.
当您使用完您的 时Connection
,您需要通过调用其close()
方法来显式关闭它,以释放连接可能保留的任何其他数据库资源(游标、句柄等)。
Actually, the safe pattern in Java is to close your ResultSet
, Statement
, and Connection
(in that order) in a finally
block when you are done with them, something like that:
实际上,在Java的安全模式是关闭的ResultSet
,Statement
和Connection
(按顺序)的finally
块,当你与他们做了,这样的事情:
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// Do stuff
...
} catch (SQLException ex) {
// Exception handling stuff
...
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) { /* ignored */}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) { /* ignored */}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) { /* ignored */}
}
}
The finally
block can be slightly improved into (to avoid the null check):
该finally
块可以稍微改进为(以避免空检查):
} finally {
try { rs.close(); } catch (Exception e) { /* ignored */ }
try { ps.close(); } catch (Exception e) { /* ignored */ }
try { conn.close(); } catch (Exception e) { /* ignored */ }
}
But, still, this is extremely verbose so you generally end up using an helper class to close the objects in null-safe helper methods and the finally
block becomes something like that:
但是,这仍然非常冗长,因此您通常最终会使用帮助类来关闭空安全帮助方法中的对象,并且finally
块会变成这样:
} finally {
DbUtils.closeQuietly(rs);
DbUtils.closeQuietly(ps);
DbUtils.closeQuietly(conn);
}
And, actually, the Apache Commons DbUtilshas a DbUtils
class which is precisely doing that so there is no need to write your own.
而且,实际上,Apache Commons DbUtils有一个DbUtils
类正是这样做的,因此无需编写自己的类。
回答by Alex Miller
Yes, you need to close the Connection. Otherwise, the database client will typically keep the socket connection and other resources open.
是的,您需要关闭连接。否则,数据库客户端通常会保持套接字连接和其他资源打开。
回答by Brian Agnew
Yes. You need to close the resultset, the statement and the connection. If the connection has come from a pool, closing it actually sends it back to the pool for reuse.
是的。您需要关闭结果集、语句和连接。如果连接来自池,关闭它实际上将它发送回池以供重用。
You typically have to do this in a finally{}
block, such that if an exception is thrown, you still get the chance to close this.
您通常必须在finally{}
块中执行此操作,这样如果抛出异常,您仍然有机会关闭它。
Many frameworks will look after this resource allocation/deallocation issue for you. e.g. Spring's JdbcTemplate. Apache DbUtilshas methods to look after closing the resultset/statement/connection whether null or not (and catching exceptions upon closing), which may also help.
许多框架会为您处理这个资源分配/解除分配问题。例如 Spring 的JdbcTemplate。Apache DbUtils有方法来处理关闭结果集/语句/连接是否为空(并在关闭时捕获异常),这也可能有所帮助。
回答by Grigori A.
It is enough to close just Statement
and Connection
. There is no need to explicitly close the ResultSet
object.
仅关闭Statement
and就足够了Connection
。无需显式关闭ResultSet
对象。
Java documentation says about java.sql.ResultSet
:
Java 文档说java.sql.ResultSet
:
A ResultSet object is automatically closed by the Statement object that generated it when that Statement object is closed, re-executed, or is used to retrieve the next result from a sequence of multiple results.
当 Statement 对象关闭、重新执行或用于从多个结果的序列中检索下一个结果时,ResultSet 对象会被生成它的 Statement 对象自动关闭。
Thanks BalusC for comments: "I wouldn't rely on that. Some JDBC drivers fail on that."
感谢 BalusC 的评论:“我不会依赖它。一些 JDBC 驱动程序会失败。”
回答by Yadu Krishnan
It is always better to close the database/resource objects after usage.
Better to close connection, resultset and statement objects in the finally
block.
使用后关闭数据库/资源对象总是更好。最好关闭块中的连接、结果集和语句对象finally
。
Until Java7, all these resources needs to be closed using a finally
block.
If you are using Java 7, then for closing the resources you can do as follows.
在 Java7 之前,所有这些资源都需要使用finally
块来关闭。如果您使用的是 Java 7,那么对于关闭资源,您可以执行以下操作。
try(Connection con = getConnection(url, username, password, "org.postgresql.Driver");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
) {
//statements
}catch(....){}
Now, con, stmt and rs objects become part of try block and java automatically closes these resources after use.
现在,con、stmt 和 rs 对象成为 try 块的一部分,java 会在使用后自动关闭这些资源。
Hope I was helpful.
希望我有帮助。
回答by Joe
Actually, it is best if you use a try-with-resources block and Java will close all of the connections for you when you exit the try block.
实际上,最好使用 try-with-resources 块,当您退出 try 块时,Java 将为您关闭所有连接。
You should do this with any object that implements AutoClosable.
您应该对任何实现 AutoClosable 的对象执行此操作。
try (Connection connection = getDatabaseConnection(); Statement statement = connection.createStatement()) {
String sqlToExecute = "SELECT * FROM persons";
try (ResultSet resultSet = statement.execute(sqlToExecute)) {
if (resultSet.next()) {
System.out.println(resultSet.getString("name");
}
}
} catch (SQLException e) {
System.out.println("Failed to select persons.");
}
The call to getDatabaseConnection is just made up. Replace it with a call that gets you a JDBC SQL connection or a connection from a pool.
对 getDatabaseConnection 的调用刚刚完成。将其替换为获取 JDBC SQL 连接或来自池的连接的调用。