tomcat连接池未关闭连接?

tomcat连接池未关闭连接?,tomcat,connection,pool,Tomcat,Connection,Pool,我在使用tomcat连接池的第三方应用程序中遇到了一些问题 除了解决这些问题外,我们还希望通过设置以下内容来释放空闲会话: minEvictableIdleTimeMillis = 60000 timeBetweenEvictionRunsMillis = 60000 但不知何故,这些会话似乎根本没有发布(即使没有任何流量): 这显示了肯定超过1分钟的“旧”会话/游标和语句 我是否错过了另一个选择? 谢谢和干杯,E.这是一个非常棘手的话题 前言 连接池的设计,一方面限制对数据库的最大同时开放

我在使用tomcat连接池的第三方应用程序中遇到了一些问题

除了解决这些问题外,我们还希望通过设置以下内容来释放空闲会话:

minEvictableIdleTimeMillis =  60000
timeBetweenEvictionRunsMillis = 60000
但不知何故,这些会话似乎根本没有发布(即使没有任何流量):

这显示了肯定超过1分钟的“旧”会话/游标和语句

我是否错过了另一个选择?
谢谢和干杯,E.

这是一个非常棘手的话题

前言

连接池的设计,一方面限制对数据库的最大同时开放连接,另一方面重用池中的开放连接

建立到数据库的物理连接需要时间。通过保持连接打开(在池中),可以“节省”此时间

连接处理

在Java7之前,您必须确保在使用连接后关闭连接。主要是在最后一个街区:

Connection conn = [retrieve DB-Connection];
try {
    // do something
} catch (SQLException e) {
    // handle exception
} finally {
    conn.close();
}
与连接池结合使用时,连接不是物理关闭的,它只是在关闭
语句
s和
结果集
s后释放到连接池中,以便重新使用

自java 7以来,上述代码应该/可以如下所示:

try (Connection conn = [retrieve DB-Connection]) {
    // do something
} catch (SQLException e) {
    // handle exception
}
这是一个新的“利用资源尝试捕获”功能。每当try块离开时,try的parantises中的资源都会关闭(可自动关闭)。偏执狂可以包含严重的、分号分隔的自动关闭资源

try (Connection conn = [retrieve DB-Connection];
     Statement stat = conn.createStatement();
     ResultSet result = stat.executeQuery("SELECT 1 FROM DUAL")) {
    // do something
} catch (SQLException e) {
    // handle exception
}
如果连接不是手动关闭/释放的,或者不是由“try catch with resources”处理的,则连接池具有一个可配置的后备功能—放弃功能,该功能处理未关闭/未释放(放弃)的连接

请参阅的tomcat版本相关文档。此链接与9.0版相关

默认情况下禁用放弃功能,可以使用 以下属性:

  • RemoveBandoned-true或false:是否删除已放弃的 来自池的连接。默认值:false
  • RemoveBandonedTimeout-删除 假定借用的连接被占用的秒数 被遗弃的。默认值:300
  • LOGREADTED-true或false:是否记录日志 放弃语句或命令的应用程序代码的堆栈跟踪 连接。这增加了严重的开销。默认值:false
游标和“ORA游标超出”-异常

打开游标的最大数目是一个可变数据库属性

因此,通过在一个连接中执行大量查询,而不是关闭“先前”打开/创建的结果集和语句,可能会发生
ORA异常

下面的示例导致五个打开的游标。在这种情况下,将使用try catch with resources,并通过退出try块自动关闭
结果集
s、
语句
s和
连接

try (Connection conn = [retrieve DB-Connection];
     Statement stat0 = conn.createStatement();
     ResultSet result0 = stat0.executeQuery(...);
     Statement stat1 = conn.createStatement();
     ResultSet result1 = stat1.executeQuery(...);
     Statement stat2 = conn.createStatement();
     ResultSet result2 = stat2.executeQuery(...);
     Statement stat3 = conn.createStatement();
     ResultSet result3 = stat3.executeQuery(...);
     Statement stat4 = conn.createStatement();
     ResultSet result4 = stat4.executeQuery(...);) {
    // do something
} catch (SQLException e) {
    // handle exception
}
最好将它们分开:

try (Connection conn = [retrieve DB-Connection]) {
    try (Statement stat0 = conn.createStatement();
         ResultSet result0 = stat0.executeQuery(...)) {
        // do something
    }
    try (Statement stat1 = conn.createStatement();
         ResultSet result1 = stat1.executeQuery(...)) {
        // do something
    }
    try (Statement stat2 = conn.createStatement();
         ResultSet result2 = stat2.executeQuery(...)) {
        // do something
    }
    try (Statement stat3 = conn.createStatement();
         ResultSet result3 = stat3.executeQuery(...)) {
        // do something
    }
    try (Statement stat4 = conn.createStatement();
         ResultSet result4 = stat4.executeQuery(...);) {
        // do something
    }
} catch (SQLException e) {
    // handle exception
}
在java 7之前,如果未手动关闭
语句
s和
结果集
s,并且连接本身未关闭/释放,也可能发生错误

下面的示例是一个“错误实践”示例,
ResultSet
s和
语句
s以及
连接
均未关闭

Connection conn = [retrieve DB-Connection];
try {
    Statement stat0 = conn.createStatement();
    ResultSet result0 = stat0.executeQuery(...);
    Statement stat1 = conn.createStatement();
    ResultSet result1 = stat1.executeQuery(...);
    Statement stat2 = conn.createStatement();
    ResultSet result2 = stat2.executeQuery(...);
    Statement stat3 = conn.createStatement();
    ResultSet result3 = stat3.executeQuery(...);
    Statement stat4 = conn.createStatement();
    ResultSet result4 = stat4.executeQuery(...);
} catch (SQLException e) {
    // handle exception
} 
让我们假设开放游标的最大值为20,并且有一个错误的实践代码段,应用程序可能会非常快地运行到“oracursorexcept”异常中

在本例中,连接池

放弃特征

为您提供服务,关闭/释放连接,并隐式地在其中执行
语句
s和
结果集
s

结论

放弃特征

这只是一种退路


最好确保正确处理和关闭
结果集
s、
语句
s和
连接
s。

谢谢!真正有助于理解和获取一些背景信息!
Connection conn = [retrieve DB-Connection];
try {
    Statement stat0 = conn.createStatement();
    ResultSet result0 = stat0.executeQuery(...);
    Statement stat1 = conn.createStatement();
    ResultSet result1 = stat1.executeQuery(...);
    Statement stat2 = conn.createStatement();
    ResultSet result2 = stat2.executeQuery(...);
    Statement stat3 = conn.createStatement();
    ResultSet result3 = stat3.executeQuery(...);
    Statement stat4 = conn.createStatement();
    ResultSet result4 = stat4.executeQuery(...);
} catch (SQLException e) {
    // handle exception
}