当前位置: 首页 > 知识库问答 >
问题:

Tomcat连接池&空闲连接

吕寒
2023-03-14
    null
 <Resource
    auth="Container"
    name="jdbc/postgres"
    factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
    type="javax.sql.DataSource"

    username="admin"
    password="..."

    driverClassName="org.postgresql.Driver"
    url="jdbc:postgresql://127.0.0.1:5432/..."
    initialSize="1"
    maxActive="50"
    minIdle="0"
    maxIdle="3"
    maxWait="-1"
    minEvictableIdleTimeMillis="1000"
    timeBetweenEvictionRunsMillis="1000"
    />

如果我理解正确的话,我们应该在启动时有1个空闲连接,根据负载从0到3,对吗?

正在发生的情况是:启动时1个连接,如果负载较低,最多3个空闲连接,高负载后超过3个空闲连接。然后这些连接不会立即关闭,我们不知道它们何时/是否会关闭(有时它们中的一些会关闭)。

所以问题是:这种行为正常吗?

public class PostgreSQLConnectionProvider {

    public static Connection getConnection() throws NamingException, SQLException {

        String dsString = "java:/comp/env/jdbc/postgres";
        Context context = new InitialContext();
        DataSource ds = (DataSource) context.lookup(dsString);
        Connection connection = ds.getConnection();

        return connection;
    }
}
public abstract class DAO implements java.lang.AutoCloseable {

    // Private attributes :
    private Connection _connection;

    // Constructors :
    public DAO() {

        try { _connection = PostgreSQLConnectionProvider.getConnection(); }
        catch (NamingException | SQLException ex) { 
            Logger.getLogger(DAO.class.getName()).log(Level.SEVERE, null, ex); 
        }
    }

    // Getters :
    public Connection getConnection() { return _connection; }

    // Closeable :
    @Override
    public void close() throws SQLException {

        if(!_connection.getAutoCommit()) {

            _connection.rollback();
            _connection.setAutoCommit(true);
        }

        _connection.close();
    }
}
public class UserDAO extends DAO {

    public User getUserWithId(int id) throws SQLException {

        PreparedStatement ps = null;
        ResultSet rs = null;

        User user = null;

        try {

            String sql = "select * from \"USER\" where id_user = ?;";

            ps = getConnection().prepareStatement(sql);
            ps.setInt(1, id);

            rs = ps.executeQuery();
            rs.next();

            String login = rs.getString("login");
            String password = rs.getString("password");
            String firstName = rs.getString("first_name");
            String lastName = rs.getString("last_name");
            String email = rs.getString("email");

            user = new User(id, login, password, firstName, lastName, email);
        }
        finally {

            if(rs != null) rs.close();
            if(ps != null) ps.close();
        }

        return user;
    }
}

DAO子类的使用示例:

try(UserDAO dao = new UserDAO()) {

    try {

        User user = dao.getUserWithId(52);
    }
    catch (SQLException ex) {

        // Handle exeption during getUserWithId
    }
}
catch (SQLException ex) {

    // Handle exeption during dao.close()
}

共有1个答案

戚宏浚
2023-03-14

从代码中可以看出,连接似乎是在DAO的生存期内获取的,而不是在语句的生存期内,这是通常的预期。通常,您会在执行语句时从池中获取一个连接,并在完成后调用close()将其返回到池中。

此外,在finally子句中,rs.close()ps.close()都可能引发异常,导致错过对准备好的语句的最后一次调用。

在Java7中,还可以使用try with resources语句,它将为您关闭准备好的语句和连接。根据规范,驱动程序应该在语句关闭时为您关闭结果。

 类似资料:
  • 我对HikariCP很陌生,我遇到了一个问题。我有一个使用hikaridaTasource从数据库获取连接的方法: 但是,当我检查pgAdmin(这是一个PostgreSQL db btw)时,我看到它没有使用空闲连接,而是创建了一堆新连接。我怎么才能修好这个? 您可以看到,在第一个图像中有19个连接,其中18个是空闲的。但是,在查询之后,会有一堆新的连接,其中大多数是空闲的。我配置Hikari错

  • > 可能是我有这个确切的问题https://github.com/brettwooldridge/hikaricp/issues/109在我的例子中,活动连接随着每个事务的增加而增加。 HikariCP-连接不可用这也是一个相同的问题。但没有人对此提供明确的解决方案。顺便说一句,我使用了begging中的。

  • 我们有一个spring-boot应用程序,它使用嵌入式tomcat进行部署,并使用MySQL后端的默认tomcat-jdbc连接池,而没有为MySQL或tomcat端定制。 该应用程序有一些调度程序,它们主要在一天中的特定时间运行,即在昨天的最后一次cron运行和今天的第一次cron运行之间,有超过9个小时的间隙。然而,无论何时cron在早期运行,它都从未遇到过空闲连接问题。 现在我们看到一条错误

  • 在配置DBCP2池时,根据文档,我注意到-有一个名为timebetweenvictionrunsmillis的配置,描述如下: 空闲对象逐出器线程运行之间的Hibernate毫秒数。如果为非正,则不会运行空闲对象逐出器线程。 其默认值为-1。 这是否意味着逐出器线程永远不会在默认配置下运行?那么配置参数maxIdle是如何强制的?如果空闲连接的计数大于maxIdle,池必须退出空闲连接。 默认配置

  • 我们有一个应用程序使用Hibernate连接到postgre数据库。我们使用C3P0作为连接池。 org.hibernate.ejb.hibernatepersistence ---类--- 正在保存对象: 正在加载对象: 创建EntityManagerFactory并获取EntityManager: 在日志中,我看到了以下内容,但我不知道它是否与我们的问题有关: 谢谢你的帮助!:)

  • 我在项目中使用ApacheTomcat JDBC连接池。我很困惑,因为在重负下,我一直看到以下错误: 我的期望是,使用池,新连接的请求将被保留在队列中,直到连接可用。相反,当池达到容量时,请求似乎会被拒绝。这种行为可以改变吗? 谢谢, 达尔 这是我的池配置: