Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HikariPool达到最大连接_Java_Sqlite_Jdbc_Hikaricp_Connection Leaks - Fatal编程技术网

Java HikariPool达到最大连接

Java HikariPool达到最大连接,java,sqlite,jdbc,hikaricp,connection-leaks,Java,Sqlite,Jdbc,Hikaricp,Connection Leaks,我正在使用HikariCP运行SQLite数据库。 我的配置如下所示: public class SQLiteDataSource { private static final HikariConfig config = new HikariConfig(); private static final HikariDataSource ds; static { config.setJdbcUrl("jdbc:sqlite:database.db");

我正在使用HikariCP运行SQLite数据库。 我的配置如下所示:

public class SQLiteDataSource {
    private static final HikariConfig config = new HikariConfig();
    private static final HikariDataSource ds;

    static {


        config.setJdbcUrl("jdbc:sqlite:database.db");
        config.setConnectionTestQuery("SELECT 1");
        config.addDataSourceProperty("cachePrepStmts", true);
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSwlLimit", "2048");
        config.setIdleTimeout(10000);
        config.setMaxLifetime(30000);
        config.setValidationTimeout(30000);
        config.setMaximumPoolSize(100);
        config.setMinimumIdle(10);
        config.setAllowPoolSuspension(false);

        ds = new HikariDataSource(config);
    }

    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }
}
// This is a slightly abreviated function to get a boolean from a table in the database where the primary key "id" matches the one requested

 public static Boolean getBoolean(String Id, String column) {
        try (final PreparedStatement preparedStatement = SQLiteDataSource.getConnection()
                // language=SQLite
                .prepareStatement("SELECT " + column + " FROM table WHERE id = ?")) {

            preparedStatement.setString(1, Id);

            try (final ResultSet resultSet = preparedStatement.executeQuery()) {
                if (resultSet.next()) {
                    Boolean bool = resultSet.getBoolean(setting);
                    resultSet.close();
                    preparedStatement.getConnection().close();
                    return bool;
                }
            }

            preparedStatement.getConnection().close();

        } catch (SQLException e) {
        e.printStackTrace();
        }
        return false;
    }
方法
getConnection()
用于从数据库中的表中获取数据。 这些函数如下所示:

public class SQLiteDataSource {
    private static final HikariConfig config = new HikariConfig();
    private static final HikariDataSource ds;

    static {


        config.setJdbcUrl("jdbc:sqlite:database.db");
        config.setConnectionTestQuery("SELECT 1");
        config.addDataSourceProperty("cachePrepStmts", true);
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSwlLimit", "2048");
        config.setIdleTimeout(10000);
        config.setMaxLifetime(30000);
        config.setValidationTimeout(30000);
        config.setMaximumPoolSize(100);
        config.setMinimumIdle(10);
        config.setAllowPoolSuspension(false);

        ds = new HikariDataSource(config);
    }

    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }
}
// This is a slightly abreviated function to get a boolean from a table in the database where the primary key "id" matches the one requested

 public static Boolean getBoolean(String Id, String column) {
        try (final PreparedStatement preparedStatement = SQLiteDataSource.getConnection()
                // language=SQLite
                .prepareStatement("SELECT " + column + " FROM table WHERE id = ?")) {

            preparedStatement.setString(1, Id);

            try (final ResultSet resultSet = preparedStatement.executeQuery()) {
                if (resultSet.next()) {
                    Boolean bool = resultSet.getBoolean(setting);
                    resultSet.close();
                    preparedStatement.getConnection().close();
                    return bool;
                }
            }

            preparedStatement.getConnection().close();

        } catch (SQLException e) {
        e.printStackTrace();
        }
        return false;
    }
每次调用函数时,PreparedStatement的连接都会在末尾关闭。 但是,池大小会不断增长,直到达到最大池大小并超时


有什么方法可以阻止此操作或强制关闭连接吗?

删除@Nithin建议的
preparedStatement.getConnection().close()
,并在try with resources块中显式获取连接:

try (Connection con = SQLiteDataSource.getConnection();final PreparedStatement preparedStatement = con
                // language=SQLite
                .prepareStatement("SELECT " + column + " FROM table WHERE id = ?")) {

这样,连接也将在块的末尾关闭。

Remove
preparedStatement.getConnection().close()
正如@Nithin所建议的那样,并在try with resources块中显式获取连接:

try (Connection con = SQLiteDataSource.getConnection();final PreparedStatement preparedStatement = con
                // language=SQLite
                .prepareStatement("SELECT " + column + " FROM table WHERE id = ?")) {

这样,连接也将在块的末尾关闭,因为块中没有保留引用,所以正在泄漏连接。因此,用于创建语句的连接永远不会关闭。相反,您将获得一个不同的连接,并关闭它(在两个不同的点!)。最终,您将以这种方式耗尽连接池

另外,如果您使用的是try-with-resources,则不需要显式关闭
resultSet

您需要将代码更改为:

try (Connection connection = SQLiteDataSource.getConnection();
     PreparedStatement preparedStatement = connection
            .prepareStatement("SELECT " + column + " FROM table WHERE id = ?")) {

    preparedStatement.setString(1, Id);

    try (ResultSet resultSet = preparedStatement.executeQuery()) {
        if (resultSet.next()) {
            Boolean bool = resultSet.getBoolean(setting);
            return bool;
        }
    }
} catch (SQLException e) {
    e.printStackTrace();
}

还要注意,如果
列的值来自不受信任的源,则容易受到SQL注入的攻击。

由于块中没有保留引用,因此正在泄漏连接。因此,用于创建语句的连接永远不会关闭。相反,您将获得一个不同的连接,并关闭它(在两个不同的点!)。最终,您将以这种方式耗尽连接池

另外,如果您使用的是try-with-resources,则不需要显式关闭
resultSet

您需要将代码更改为:

try (Connection connection = SQLiteDataSource.getConnection();
     PreparedStatement preparedStatement = connection
            .prepareStatement("SELECT " + column + " FROM table WHERE id = ?")) {

    preparedStatement.setString(1, Id);

    try (ResultSet resultSet = preparedStatement.executeQuery()) {
        if (resultSet.next()) {
            Boolean bool = resultSet.getBoolean(setting);
            return bool;
        }
    }
} catch (SQLException e) {
    e.printStackTrace();
}

还要注意,如果
列的值
来自不受信任的源,则易受SQL注入攻击。

我认为不需要显式关闭连接
preparedStatement.getConnection().close()
我认为不需要显式关闭连接
preparedStatement.getConnection().close()