首页
论坛
图书
开发资料
在线文档
网址
下载
联系我们
 新闻│Java│JavaScript│Eclipse│Eclipse 英文│J2EE│J2ME│J2SE│JSP│Netbeans│Hibernate│JBuilder│Spring│Struts
站内搜索: 请输入搜索关键词

当前页面: 开发资料首页 → Java 专题 → 堵塞连接泄漏

堵塞连接泄漏

摘要: 堵塞连接泄漏

</td> </tr> <tr> <td height="35" valign="top" class="ArticleTeitle"> <table width="675" border="0"> <tr> <td width="389">堵塞连接泄漏

看看下面的代码:

Datasource source=...
Connection conn=source.getConnection();
Statement stat=conn.createStatement();
String command="insert into User values("root","123456");
stat.executeUpdate(command);
conn.close();

上面代码看上去很整洁:我们打开一个连接,发送命令,并立即关闭连接。但是,这里有一个致命的错误。如果某一方法调用抛出一个异常,则永远无法调用close()方法!在这里,生气的用户可能会多次重新提交请求,每次单击都会泄漏一个连接对象。要解决这个问题,就要在finally块中放置close()调用:
</td> <td width="276"> </td> </tr> </table>

Datasource source=...
Connection conn=source.getConnection();
try{
Statement stat=conn.createStatement();
String command="insert into User values("root","123456");
stat.executeUpdate(command);

}
finally{
conn.close();
}

这个简单的规则完全可以解决连接泄漏的问题,但它没有处理异常,如果象下面那样:

Datasource source=...
Connection conn=null;
try{
conn=source.getConnection();
Statement stat=conn.createStatement();
String command="insert into User values("root","123456");
stat.executeUpdate(command);

}
catch(SQLExceptin e){
//日志记录
}
finally{
conn.close();
}

代码中又有两个小错误。首先,如果调用getConnection会抛出一个异常,而conn仍然是null,这时将不能调用close()。此外,调用close()也会抛出SQLException。正确的代码应该为:

Datasource source=...
try{
Connection conn=source.getConnection();
try{
Statement stat=conn.createStatement();
String command="insert into User values("root","123456");
stat.executeUpdate(command);
}
finally{
conn.close();
}
}
catch(SQLException e){
//日志记录
}

内部的try语句块确保连接被关闭,外部的try语句块确保异常被记录。
当然,还可以使用throws SQLException来标注方法并将外部try语句块留给调用者处理。如:

boolean loggedIN;
public void doLogin() throws SQLException, NamingException {
Context ctx = new InitialContext();
if (ctx == null) throw new NamingException("No initial context");

DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/mydb");
if (ds == null) throw new NamingException("No data source");

Connection conn = ds.getConnection();
if (conn == null) throw new SQLException("No connection");

try {
PreparedStatement passwordQuery = conn.prepareStatement(
"SELECT password from Users WHERE username = ?");

passwordQuery.setString(1, name);

ResultSet result = passwordQuery.executeQuery();

if (!result.next()) return;
String storedPassword = result.getString("password");
loggedIn = password.equals(storedPassword.trim());
}
finally {
conn.close();
}
}

这是调用这个方法的代码:
public String login() {
try {
doLogin();
}
catch (SQLException ex) {
logger.log(Level.SEVERE, "loginAction", ex);
return "internalError";
}
catch (NamingException ex) {
logger.log(Level.SEVERE, "loginAction", ex);
return "internalError";
}
if (loggedIn)
return "loginSuccess";
else
return "loginFailure";
}

function TempSave(ElementID) { CommentsPersistDiv.setAttribute("CommentContent",document.getElementById(ElementID).value); CommentsPersistDiv.save("CommentXMLStore"); } function Restore(ElementID) { CommentsPersistDiv.load("CommentXMLStore"); document.getElementById(ElementID).value=CommentsPersistDiv.getAttribute("CommentContent"); } </td> </tr> <tr>


↑返回目录
前一篇: 使用JdbcRowSet和CachedRowSet的例子
后一篇: 通过JDBC、Hibernate API访问数据库图示

首页 | 全站 Sitemap | 联系我们 | 设为首页 | 收藏本站
版权所有 Copyright © 2006-2007, Java 编程资料牛鼻站, All rights reserved