Connection.close()不会关闭连接,它会使它永远休眠吗?

时间:2018-08-27 10:21:28

标签: java sql-server jdbc tomcat8

在我用Java编写并使用tomcat和sql server的Web应用程序中,无法通过键入connection.close()关闭数据库连接。当我将sp_who写入SSMS时,我可以看到在我的应用程序执行sql填充操作时,由我打开的睡眠连接计数增加了。

下面是一个示例代码:

BaseRepository baseRepository = new BaseRepository();
try{
    baseRepository.createStatement();

    baseRepository.stmt.executeUpdate("update AutoRunURLs set STATUS = 0");

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

这是我上面使用的其他功能:

public void openConnection() {
    try {
        this.conn = ds.getConnection(); // ds is an instance of javax.sql.DataSource
        this.isOpen = true;
    } 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 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();
    }
}

当我运行以BaseRepository baseRepository ...开头的第一部分时,会出现一个睡眠连接,通过键入sp_who可以看到它并没有关闭(我等待了一天)。这是为什么?我该如何预防?

我又遇到了一种情况。在我的tomcat配置中,我将“ maxIdle”值设置为10,但是即使一个星期后睡眠连接也增加到数千。为什么maxIdle不起作用?这是我的设置方式:

<Context>

<!-- Default set of monitored resources. If one of these changes, the    -->
<!-- web application will be reloaded.                                   -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<Resource auth="Container" driverClassName="net.sourceforge.jtds.jdbc.Driver" maxTotal="999999" maxIdle="10" "Database info here..." validationQuery="select 1"/>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->

如何解决这些问题?问候


编辑:我实际上是通过创建一个计划任务来管理它的,该任务每x分钟运行一次,并杀死超过y分钟的睡眠连接。但这不是我想要的方式。任何其他解决方案都很好。

1 个答案:

答案 0 :(得分:1)

您正在使用Tomcat内置的连接池。这意味着它将保持连接打开以供重用。当您关闭代码中的连接时,它们实际上并没有关闭,而是返回到池中供您的应用程序重新使用。由于打开新连接需要时间,因此可以提高效率。

换句话说,没有什么错,并且保持打开状态的连接是预期的行为。

您可能希望将maxTotal降低到更合理的值,例如10-20,而不是999999。

顺便说一句,您处理连接的方式有点奇怪,并且很容易泄漏连接。您可能只想在真正需要时从数据源获取连接,并了解try-with-resources,以便尽快关闭它。