在运行于Tomcat的Java Web项目中,两天后有超过4000个睡眠连接(我使用sp_who命令检查了它们)。完成数据库工作后,我确实关闭了所有语句,结果集和连接。我将以下模板用于数据库内容。
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中):
maxTotal="20" maxActive="20" maxIdle="20"
答案 0 :(得分:1)
您用于清洁连接的代码/图案有缺陷:
try {
this.openConnection();
this.createStatement();
// things ...
this.cleanResources();
} catch (SQLException e){
this.cleanResources();
e.printStackTrace();
}
如果“事物”引发某些非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();
}
}
在某些情况下,这些缺陷中的任何一个都可能导致数据库连接泄漏。
另一种可能性是您在代码中的某个地方没有遵循(有缺陷的)模式。
我认为您需要阅读以下内容:
还值得注意的是,以下做法是错误的做法:
Exception
...在大多数情况下