[英]Connection close does not close the connections in Tomcat
在我的運行於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"
您用於清潔連接的代碼/模式存在缺陷:
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
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.