jb.*_*jb. 49 java findbugs jdbc
我一直在对我们的宠物项目之一进行代码审查(主要使用像FindBugs这样的工具),FindBugs将以下代码标记为错误(伪代码):
Connection conn = dataSource.getConnection();
try{
PreparedStatement stmt = conn.prepareStatement();
//initialize the statement
stmt.execute();
ResultSet rs = stmt.getResultSet();
//get data
}finally{
conn.close();
}
Run Code Online (Sandbox Code Playgroud)
错误是此代码可能不会释放资源.我发现ResultSet和Statement没有关闭,所以我最后关闭了它们:
finally{
try{
rs.close()
}catch(SqlException se){
//log it
}
try{
stmt.close();
}catch(SqlException se){
//log it
}
conn.close();
}
Run Code Online (Sandbox Code Playgroud)
但是我在很多项目中遇到过上述模式(来自不少公司),没有人关闭ResultSet或Statements.
在Connection关闭时,您是否遇到没有关闭ResultSet和Statements的麻烦?
我发现只有这个,它指的是Oracle在关闭Connections时关闭ResultSet的问题(我们使用Oracle db,因此我的更正).java.sql.api在Connection.close()javadoc中什么也没说.
Aar*_*ron 52
仅关闭连接而不是结果集的一个问题是,如果您的连接管理代码使用连接池,则只connection.close()会将连接放回池中.此外,某些数据库在服务器上有一个游标资源,除非明确关闭,否则不会正确释放.
neu*_*242 28
即使连接已关闭,我在Oracle中未解决的ResultSet也遇到了问题.我得到的错误是
"ORA-01000: maximum open cursors exceeded"
Run Code Online (Sandbox Code Playgroud)
所以:始终关闭ResultSet!
小智 19
您应该始终显式关闭所有JDBC资源.正如Aaron和John已经说过的那样,关闭连接通常只会将它返回到池中,并不是所有的JDBC驱动程序都以完全相同的方式实现.
这是一个可以在finally块中使用的实用方法:
public static void closeEverything(ResultSet rs, Statement stmt,
Connection con) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Oracle会向您提供有关打开游标的错误.
根据:http://java.sun.com/javase/6/docs/api/java/sql/Statement.html
看起来重用一个语句将关闭所有打开的结果集,关闭一个语句将关闭所有结果集,但我没有看到关闭连接的任何内容将关闭它创建的任何资源.
所有这些细节都留给JDBC驱动程序提供程序.
最明确地关闭一切是最安全的.我们写了一个util类,用try {xxx} catch(Throwable {}包装所有东西,这样你就可以调用Utils.close(rs)和Utils.close(stmt)等,而不必担心关闭扫描的异常会抛出.
ODBC桥可以使用一些ODBC驱动程序产生内存泄漏.
如果您使用一个好的JDBC驱动程序,那么关闭连接应该没有任何问题.但是有两个问题:
最好的做法是关闭它.
我在一个大型的J2EE Web环境中工作.我们有几个可以在单个请求中连接的数据库.我们开始在一些应用程序中遇到逻辑死锁.问题是如下:
出现这种情况有两个原因,我们遇到的流量远远高于正常情况,默认情况下,J2EE规范实际上并没有关闭您的连接,直到线程完成执行.因此,在上面的示例中,步骤4实际上从未实际关闭连接,即使它们最终正确关闭.
要解决此问题,您必须在web.xml中使用资源引用作为数据库连接,并且必须将res-sharing-scope设置为unharable.
例:
<resource-ref>
<description>My Database</description>
<res-ref-name>jdbc/jndi/pathtodatasource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
63212 次 |
| 最近记录: |