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

即使我的所有代码都调用了close方法,HikariCP也会检测到connectionleak

宫俊才
2023-03-14

我在我们的web应用程序中使用HikariCP,突然,我遇到了以下异常:

    [Hikari housekeeper (pool HikariPool-0)] WARN com.zaxxer.hikari.pool.ProxyLeakTask - Connection leak detection triggered for connection com.mysql.cj.jdbc.ConnectionImpl@3b82d04f, stack trace follows

java.lang.异常:检测到明显的连接泄漏

我已经检查并确保我的所有sql代码都调用了close方法。

这是我的HikariConfig:

    private HikariConfig hikariConfig() {
    HikariConfig config = new HikariConfig();
    config.setDriverClassName(CLASS_FOR_NAME);
    config.setJdbcUrl(HOST);
    config.setUsername(USER);
    config.setPassword(PASS);
    config.addDataSourceProperty("cachePrepStmts", "true");
    config.addDataSourceProperty("prepStmtCacheSize", "250");
    config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
    config.setLeakDetectionThreshold(TimeUnit.SECONDS.toMillis(30));
    config.setValidationTimeout(TimeUnit.MINUTES.toMillis(1));
    config.setMaximumPoolSize(40);
    config.setMinimumIdle(0);
    config.setMaxLifetime(TimeUnit.MINUTES.toMillis(2)); // 120 seconds max life time
    config.setIdleTimeout(TimeUnit.MINUTES.toMillis(1)); // minutes
    config.setConnectionTimeout(TimeUnit.MINUTES.toMillis(5)); // millis
    config.setConnectionTestQuery("/* ping */ SELECT 1");

    return config;
}

以下是我的查询的样子:

   public ArrayList<LocationType> getLocationTypes() {
    ArrayList<LocationType> locationTypes = new ArrayList<>();
    Connection connection = null;
    PreparedStatement pstmt = null;
    ResultSet resultSet = null;

    try {
        connection = DataSource.getInstance().getConnection();

        pstmt = connection.prepareStatement("SELECT\n" +
                "  location_type_id,\n" +
                "  location_type_name\n" +
                "FROM tablename;");

        resultSet = pstmt.executeQuery();

        while (resultSet.next()) {
            locationTypes.add(new LocationType(resultSet.getInt("location_type_id"), resultSet.getString("location_type_name")));
        }

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (resultSet != null)
            try {
                resultSet.close();
            } catch (SQLException e) {
            }

        if (pstmt != null)
            try {
                pstmt.close();
            } catch (SQLException e) {
            }

        if (connection != null)
            try {
                connection.close();
            } catch (SQLException e) {
            }
    }
    return locationTypes;
}

我已经尝试过增加connectionLeakDetection、最大连接数和最小空闲数,但都没有解决问题。

我已经读到它可能是由机器(低资源)和连接被关闭引起的,但是,我认为这些都不会导致问题。

我注意到我的代码中的一些长查询现在被检测为连接泄漏,尽管我没有调用它们的方法。我希望你们能帮忙。

这是堆栈跟踪:

    at com..database.DataSource.getConnection(DataSource.java:148)
at com.database.databaseServices.MileageReportService.MileageService.getMonthlySummaryBySID(MileageService.java:27)
at com.views.reports.mileage.MileageReport.lambda$generateReport$61446b05$1(MileageReport.java:103)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)

这条线路上唯一的线路是里程服务。java:27是我对DB的查询,它的finally调用中有一个close语句。

共有1个答案

邵崇凛
2023-03-14

升级至最新的HikariCP。

HikariCP将连接报告为泄漏,因为从借用到关闭所用的时间比指定的LeakDetectionThreshold长。

版本 2.4.9 及更高版本,它会记录连接是否在报告为泄漏后恢复。

此外,查看您的配置,我会调整属性如下(前4到1分钟,最后到5分钟):

config.setLeakDetectionThreshold(TimeUnit.MINUTES.toMillis(1));
config.setConnectionTimeout(TimeUnit.MINUTES.toMillis(1));
config.setValidationTimeout(TimeUnit.MINUTES.toMillis(1));
config.setIdleTimeout(TimeUnit.MINUTES.toMillis(1));

config.setMaxLifetime(TimeUnit.MINUTES.toMillis(5));

HTH

 类似资料:
  • 问题内容: 我想用主方法创建一个简单的Java类,但是在编译代码时,出现以下错误消息: 错误:在类error.TestErrors中找不到主方法,请将主方法定义为:public static void main(String [] args) 这是源代码: 为什么我看到此错误,如您所见,我已经声明了main方法! 问题答案: 正如我在评论中所说,您似乎已经在自己的类中声明了一个类。为了证明这一点,

  • 问题内容: 我对flush和close方法感到非常困惑。在我的代码中,我总是关闭我的对象。但是我想知道,如果我必须在这里使用冲洗方法,在哪里可以使用它? 我将编写一个反复下载4或5个文件的项目。我将编写一个方法(用于下载文件),我的方法将处于循环中并重复下载文件。我的方法将具有这样的代码。 该方法调用还是在关闭之前必须使用冲洗? 请注意,该代码运行良好:成功下载了文件。但是我不确定要使用。 问题答

  • 问题内容: 罐的价值有多种变化方式,包括: 按键 复制粘贴 用JavaScript修改 通过浏览器或工具栏自动完成 我希望我的JavaScript函数在每次更改时都能被调用(使用当前输入值)。我希望立即调用它,而不仅仅是输入失去焦点时。 我正在寻找最干净,最可靠的方法来在所有浏览器中做到这一点(最好使用jQuery)。 问题答案: 不幸的是,我认为赢得了大奖: 这是最干净的解决方案,只需一行代码。

  • 问题内容: 我正在阅读揭露java.lang.Out OfMemoryError,我想知道我是否正确理解它。的确,如果Java VM抛出 :请求的阵列大小超出VM限制 这意味着VM拒绝了数组的创建,因为它已经超出了预定义的限制(超出了VM的限制),而 不是 因为我的堆空间用完了吗? 我是否可以说这并不表示记忆不足? 即使我有 无限的 记忆 无处不在 ,Java虚拟机仍然可以抛出,如果它不喜欢我的请

  • 为什么即使在Java中使用close()方法,也会出现“Resource leak:”错误? 我把整个代码和注释放在哪里,在哪里得到错误信息,在哪里关闭Scanner方法。 我使用Eclipse,Java13。 这是密码。 甚至当我投入的时候。close()在try块中,仍然显示相同的错误。 即使我把in.close()放在后面,它仍然显示同样的错误。 为什么会这样?

  • 问题内容: 我正在使用IText库来促进applet中的pdf导出。在导出调用期间,它失败并显示以下错误: 我在JD Decompiler中打开了Itext jar / PdfPtable.class,并确认该类具有completeRow作为公共方法。 即使在jar / class拥有a的情况下,有人可以解释抛出a的可能情况吗? 这是堆栈跟踪;可能不是很有帮助,因为大多数调用是针对我们的应用程序的