繁体   English   中英

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

[英]Connection.close() does not closes the connection, it make it sleep forever?

在我用 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 ...开头的第一部分时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 分钟的睡眠连接。 但这不是我想要的方式。 任何其他解决方案都会很棒。

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

换句话说,没有任何问题,保持打开的连接是预期的行为。

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

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

暂无
暂无

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

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