Java Oracle与Tomcat 9的僵尸连接

Java Oracle与Tomcat 9的僵尸连接,java,tomcat,jdbc,ojdbc,tomcat9,Java,Tomcat,Jdbc,Ojdbc,Tomcat9,我在Tomcat 9.0.12上创建了一个非常简单的web服务,每次调用该服务时,我都使用数据源(在conf/context.xml文件中定义)创建与数据库(Oracle 12)的连接,然后在将响应返回给客户机之前,它关闭与数据库的连接 但是如果我检查数据库上的活动会话,它会显示连接仍然处于活动状态,因此我有很多到数据库的“僵尸”连接 我对客户端程序使用了或多或少相同的代码,在本例中,程序关闭了连接。可能是Tomcat的错误配置 我怎样才能解决这个问题 谢谢大家! conf/context.xm

我在Tomcat 9.0.12上创建了一个非常简单的web服务,每次调用该服务时,我都使用数据源(在conf/context.xml文件中定义)创建与数据库(Oracle 12)的连接,然后在将响应返回给客户机之前,它关闭与数据库的连接

但是如果我检查数据库上的活动会话,它会显示连接仍然处于活动状态,因此我有很多到数据库的“僵尸”连接

我对客户端程序使用了或多或少相同的代码,在本例中,程序关闭了连接。可能是Tomcat的错误配置

我怎样才能解决这个问题

谢谢大家!

conf/context.xml


他们不是僵尸。他们正在连接池中等待重用。创建连接是昂贵的,所以你不想(真的)免费关闭它们。正如Andreas指出的,连接池返回一个包装好的连接,调用
close()
并不能真正关闭它。它刚回到游泳池


您的配置表明池中最多可以有100个空闲连接,总共有200个连接。正如马克所说,这很可能是

他们不是僵尸。他们正在连接池中等待重用。创建连接是昂贵的,所以你不想(真的)免费关闭它们。正如Andreas指出的,连接池返回一个包装好的连接,调用
close()
并不能真正关闭它。它刚回到游泳池


您的配置表明池中最多可以有100个空闲连接,总共有200个连接。正如马克所说,这很可能是

“您不想无缘无故地关闭它们”为了澄清这一点,应用程序代码应该始终关闭它们,但Tomcat添加的连接池逻辑会拦截代码完成的关闭,而连接会返回到池中以供重用。当应用程序代码稍后尝试创建一个新连接时,它将从池中获取一个现有连接(快得多!)。可以对池进行优化以获得更好的性能,请参阅。“您不想无缘无故地关闭它们”为了澄清这一点,应用程序代码应该始终关闭它们,但代码完成的关闭操作会被Tomcat添加的连接池逻辑截获,而连接会返回到池中以供重用。当应用程序代码稍后尝试创建一个新连接时,它将从池中获取一个现有连接(快得多!)。可以调整池以获得更好的性能,请参阅。使用
Resource
创建连接池。另外,如果这是一个每秒不能收到数百个请求的应用程序,那么使用100 idle和200 max可能有点过头了。使用
Resource
会创建一个连接池。此外,如果这是一个每秒不能收到数百个请求的应用程序,那么使用100 idle和200 max可能有点过头了。
<Resource maxWaitMillis="5000" 
          maxIdle="100" 
          maxActive="200" 
          password="PASSWORD" 
          username="USER" 
          url="jdbc:oracle:thin:@/192.168.1.248:1521/PRD" 
          driverClassName="oracle.jdbc.driver.OracleDriver" 
          type="javax.sql.DataSource" 
          auth="Container" 
          name="jdbc_Connection"/>
public String method() {

    try {
        System.out.println("---------------------------------------");
        System.out.println("START");
        System.out.println("---------------------------------------");


        DataSource ds = (DataSource) InitialContext.doLookup("java:comp/env/jdbc_Connection");

        Connection DB = ds.getConnection();


        String sql ="SELECT VAR FROM TABLE_NAME";
        PreparedStatement stmt = null;
        try {
            stmt = DB.prepareStatement(sql);
            ResultSet rs    = stmt.executeQuery();

            while(rs.next()){
                System.out.println("rs->"+rs.getString(1));
            }

            rs.close();
            stmt.close();
        } catch (SQLException ex) {
        }finally{
            if(stmt != null){
                try {
                    stmt.close();
                } catch (SQLException ex) {

                }
            }
        }


        System.out.println("CLOSE");
        DB.close();

    } catch (SQLException ex) {
        ex.printStackTrace();
    } catch (NamingException ex) {
        ex.printStackTrace();
    } 

    System.out.println("---------------------------------------");
    System.out.println("END");
    System.out.println("---------------------------------------");


    return "HELLO";
}