Java 连接关闭不会关闭Tomcat中的连接
在我在Tomcat上运行的java web项目中,2天后有4000多个休眠连接(我用sp_who命令检查了它们)。在完成数据库作业后,我确实会关闭每个语句、结果集和连接。我使用下面的模板处理数据库内容Java 连接关闭不会关闭Tomcat中的连接,java,sql,sql-server,tomcat,Java,Sql,Sql Server,Tomcat,在我在Tomcat上运行的java web项目中,2天后有4000多个休眠连接(我用sp_who命令检查了它们)。在完成数据库作业后,我确实会关闭每个语句、结果集和连接。我使用下面的模板处理数据库内容 try{ this.openConnection(); this.createStatement(); // things ... this.cleanResources(); }catch (SQLExcepti
try{
this.openConnection();
this.createStatement();
// things ...
this.cleanResources();
}catch (SQLException e){
this.cleanResources();
e.printStackTrace();
}
public void cleanResources() {
try {
if (this.rs != null) {
rs.close();
this.rs = null;
}
if (this.stmt != null) {
stmt.close();
this.stmt = null;
}
if (this.conn != null) this.closeConnection();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (this.conn != null) this.closeConnection();
}
}
public void closeConnection() {
try {
if (this.conn != null)
this.conn.close();
this.isOpen = false;
} catch (Exception e) {
e.printStackTrace();
}
}
public void createStatement() {
try {
if (!this.isOpen) this.openConnection();
this.stmt = this.conn.createStatement();
} catch (Exception e) {
e.printStackTrace();
}
}
public void openConnection() {
try {
this.conn = ds.getConnection(); // ds is a javax.sql.DataSource instance
this.isOpen = true;
} catch (Exception e) {
e.printStackTrace();
}
}
每次sql代码运行后,处于休眠状态的行数都会增加,数据库的运行速度也会变慢。为什么会这样?我怎么能在完成连接后完全杀死它?是否真的是休眠连接使我的SQL Server变慢了
以下是我的Tomcat配置(在context.xml中):
清洁连接的代码/模式有缺陷:
try {
this.openConnection();
this.createStatement();
// things ...
this.cleanResources();
} catch (SQLException e){
this.cleanResources();
e.printStackTrace();
}
如果“things”抛出的异常不是SQLException
或子类,则不会关闭连接
如果应该:
try {
this.openConnection();
this.createStatement();
// things ...
this.cleanResources();
} catch (SQLException e) {
e.printStackTrace();
} finally {
this.cleanResources();
}
那么这个,
public void cleanResources() {
try {
if (this.rs != null) {
rs.close();
this.rs = null;
}
if (this.stmt != null) {
stmt.close();
this.stmt = null;
if (this.conn != null) this.closeConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
如果rs.close()
或stmt.close()
引发异常,则连接未关闭
应该是这样的:
public void cleanResources() {
try {
if (this.rs != null) {
rs.close();
this.rs = null;
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (this.stmt != null) {
stmt.close();
this.stmt = null;
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (this.conn != null) this.closeConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
在某些情况下,这些缺陷都可能导致数据库连接泄漏
另一种可能性是,代码中的某个地方没有遵循(有缺陷的)模式
我认为你需要仔细阅读以下内容:
- Java 7+“尝试使用资源”支持
- Java1.0+“尝试……最终”
还值得注意的是,以下做法是不好的:
- 捕获异常。。。在大多数情况下
- 挤压异常(即捕捉并静默继续)。。。在大多数情况下
- 在整个代码中分散对printStackTrace的调用
语句
和结果集
是不合适的。--但是,如果你坚持这种逻辑,至少你需要把cleanResources()
放在finally
块中。既然我们看不到openConnection()
和closeConnection()
方法做什么,我们怎么说你做得对呢?@Andreas对不起,我错过了那个,现在编辑了。@Andreas我现在要尝试在finally block中执行它。@Andreas在finally block中执行它没有任何区别,仍然处于睡眠状态的连接数正在减少。我观察到,即使没有例外,睡眠连接数也在增加。我只是在finally block中用清洁资源试了一下,但没有任何区别。在这种情况下,你做得不对。“最终”或“尝试资源”方法有效。。。如果你做得正确。如果你真的需要帮助调试你的代码,你需要提供一个MCVE(重点放在M…上,以便最小化)
public void cleanResources() {
try {
if (this.rs != null) {
rs.close();
this.rs = null;
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (this.stmt != null) {
stmt.close();
this.stmt = null;
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (this.conn != null) this.closeConnection();
} catch (Exception e) {
e.printStackTrace();
}
}