H2连接池

H2 connection pool

我想为我的 h2 数据库创建一个连接池。但我认为每次调用 getConnection() 时我的池都会打开新连接。我想应该有固定数量的可重用连接,但如果我 运行 此代码 :

Connection conn = DataSource.getInstance().getConnection();
        Statement stmt = conn.createStatement();
        ResultSet rs;
        rs = stmt.executeQuery("SELECT * FROM NODE_USERS;");
        while (rs.next()) {
            System.out.println(rs.getString("login"));
        }
        try {
            // wait a bit
            Thread.sleep(20000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        stmt.close();
        rs.close();
        conn.close();  

数据源:

public class DataSource {

    private static volatile DataSource datasource;
    private BasicDataSource ds;

    private DataSource() throws IOException, SQLException, PropertyVetoException {
        ds = new BasicDataSource();
        ds.setUsername("sa");
        ds.setPassword("sa");
        ds.setUrl("jdbc:h2:tcp://localhost/~/test");       
        ds.setMinIdle(5);
        ds.setMaxActive(10);
        ds.setMaxIdle(20);
        ds.setMaxOpenPreparedStatements(180);

    }

    public static DataSource getInstance() throws IOException, SQLException, PropertyVetoException {
        if (datasource == null) {
            synchronized (DataSource.class) {
                if (datasource == null) {
                    datasource = new DataSource();
                }
            }
            datasource = new DataSource();
        }
        return datasource;
    }

    public Connection getConnection() throws SQLException {
        return this.ds.getConnection();
    }

}

然后执行select * from information_schema.sessions;,会有两行。怎么了?我也在尝试 H2 tutorial example,但我得到了相同的结果。

您正在使用连接池,即BasicDataSource。它最初会创建配置数量的连接,然后当 getConnection() 被调用时,它会重新使用一个空闲的池连接或创建一个新的连接,直到配置的限制(或者没有限制,如果配置的话)。当获取到的连接是"closed" using Connection.close()时,实际上是返回到池中,而不是马上关闭

除了配置允许的最小和最大打开连接数之外,您基本上无法控制在给定时间内打开的连接数。因此,您观察到两个打开的连接并不能证明任何事情。如果想看是否有打开连接数限制,使用BasicDataSource.maxActive()配置BasicDataSource最多使用2个连接,然后尝试同时获取3个连接。对于另一个测试,使用相同的配置,尝试获取两个连接,使用 Connection.close() 返回它们,然后再获取另外两个连接。