简体   繁体   English

连接关闭不会关闭Tomcat中的连接

[英]Connection close does not close the connections in Tomcat

In my java web project which runs on Tomcat there are over 4000 sleeping connections after 2 day (I checked them with sp_who command). 在我的运行于Tomcat的Java Web项目中,两天后有超过4000个睡眠连接(我用sp_who命令检查了它们)。 I do close every statement, resultset and connections after I do a database job. 完成数据库工作后,我确实关闭了所有语句,结果集和连接。 I use the below template for database stuffs. 我将以下模板用于数据库。

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

After every time a sql code worked, the row counts which has sleeping status does increases and the database stuffs gets so much slower. 每次执行sql代码后,具有休眠状态的行计数确实增加,并且数据库填充变得非常慢。 Why does it happens? 为什么会发生? How can I completely kill a connection after I done with it? 完成连接后,如何完全终止连接? Is it really the sleeping connections that makes slower my SQL Server? 确实是睡眠连接使我的SQL Server变慢了吗?

Here is my Tomcat configurations(In context.xml): 这是我的Tomcat配置(在context.xml中):

maxTotal="20" maxActive="20" maxIdle="20"

Your code / pattern for cleaning connections is flawed: 您用于清洁连接的代码/模式存在缺陷:

try {
    this.openConnection();
    this.createStatement();

    // things ...

    this.cleanResources();
} catch (SQLException e){
    this.cleanResources();
    e.printStackTrace();
}

This doesn't close connections if "things" throws some exception that is not an SQLException or subclass. 如果“事物”引发某些非SQLException或子类的异常,则不会关闭连接。

If should be: 如果应该是:

try {
    this.openConnection();
    this.createStatement();

    // things ...

    this.cleanResources();
} catch (SQLException e) {
    e.printStackTrace();
} finally {
    this.cleanResources();
}

Then this: 然后这样:

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

If either rs.close() or stmt.close() throws an exception, then the connection is not closed. 如果rs.close()stmt.close()引发异常,则连接不会关闭。

It should be something like this: 应该是这样的:

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

Either of these flaws could result in leaking of database connections in some cases. 在某些情况下,这些缺陷中的任何一个都可能导致数据库连接泄漏。

Another possibility is that somewhere in your code you are not following your (flawed) pattern. 另一种可能性是在代码中的某处您没有遵循(缺陷)模式。

I think you need to read up on: 我认为您需要阅读以下内容:

  • Java 7+ "try with resources" support Java 7+“尝试资源”支持
  • Java 1.0+ "try ... finally". Java 1.0+“最终尝试...”。

It is also worth noting that it is bad practice to: 还值得注意的是,以下做法是错误的做法:

  • catch Exception ... in most cases 在大多数情况下捕获Exception ...
  • squash exceptions (ie catch and silently continue) ... in most cases 壁球异常(即抓住并默默继续)...在大多数情况下
  • scatter calls to printStackTrace throughout your code. 在整个代码中分散调用printStackTrace。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM