簡體   English   中英

連接關閉不會關閉Tomcat中的連接

[英]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();
    }
}

在某些情況下,這些缺陷中的任何一個都可能導致數據庫連接泄漏。

另一種可能性是在代碼中的某處您沒有遵循(缺陷)模式。

我認為您需要閱讀以下內容:

  • Java 7+“嘗試資源”支持
  • Java 1.0+“最終嘗試...”。

還值得注意的是,以下做法是錯誤的做法:

  • 在大多數情況下捕獲Exception ...
  • 壁球異常(即抓住並默默繼續)...在大多數情況下
  • 在整個代碼中分散調用printStackTrace。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM