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

使用Spring / JPA /光试图在我的代码中找到数据库连接漏洞

左丘阳晖
2023-03-14

我的一个Spring web应用程序遇到了一个问题,它在从我的连接池中获取连接时会周期性地出错。最终,我在日志中看到了如下条目:

  • 原因: Javax.持久性.持久性异常: 组织.Hibernate.异常.JDBC连接异常: 无法获取 JDBC 连接
  • 由以下原因引起:java.sql.SQL 瞬态连接异常:光池-1 - 连接不可用,请求在 30000 毫秒后超时。

一旦它达到这一点,我发现恢复的唯一方法是重新启动Tomcat。

我认为最可能的解释是我在某个地方有一些代码没有正确清理它的连接——把它返回给光,让一些东西打开,这样Spring就不能清理它,等等。

为了排除故障,我已将hikari配置泄漏检测阈值设置为5000ms并启用日志记录。之后,我看到日志条目,如

2018-04-24 19:53:56 WARN  ProxyLeakTask:87 - Connection leak detection 
triggered for org.postgresql.jdbc.PgConnection@664ec666, stack trace 
follows
java.lang.Exception: Apparent connection leak detected
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
    at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:35)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:99)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:129)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:47)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:146)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:148)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1940)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1909)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1887)
    at org.hibernate.loader.Loader.doQuery(Loader.java:932)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349)
    at org.hibernate.loader.Loader.doList(Loader.java:2615)
    at org.hibernate.loader.Loader.doList(Loader.java:2598)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2430)
    at org.hibernate.loader.Loader.list(Loader.java:2425)
    at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:335)
    at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2129)
    at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:981)
    at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:147)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1398)
    at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1444)
    at sun.reflect.GeneratedMethodAccessor191.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:379)
    at com.sun.proxy.$Proxy163.getSingleResult(Unknown Source)
    at com.mycompany.web.jpa.util.DBHelper.getPagedMappedDbResults(DBHelper.java:76)
    at com.mycompany.web.jpa.repository.TaskRepositoryImpl.findTaskDetailsByStepIdAndIdIn(TaskRepositoryImpl.java:245)
......

因此它正在检测可能的泄漏。我想可能是假阳性?但这也是我的应用程序中唯一一个在Spring应用程序中经常使用的标准服务/存储库模式之外进行数据库访问的类,因此它似乎是一个可能的罪魁祸首,也是我目前最好的线索。

无论如何,我在跟踪中看到的最后一段非库代码(即我写的东西,所以很可能是泄漏的原因!)是我的DBHelper::getPagedMapedDb结果方法,相关位包含在这里:

    Query q = entityManager.createNativeQuery(countQueryText);
    setQueryParameters(q, parameters);
    long numActualResults = 0;
    try {
        numActualResults = ((Number)q.getSingleResult()).longValue(); // line 76
    } catch (Exception e) {
        System.out.println("just in case: " + e);
    }

所以基本上我从我的EntityManager实例创建了一个Query对象,设置了一些参数,然后运行它以获得一些结果。

使用完查询对象后,是否需要对它执行某些操作?q.清理()?我从阅读文档中没有看到类似的东西,但是我没有在这个资源上做很好的内务管理吗?

实体管理器本身是从@Autowired批注创建的。我的理解是,如果我没有“新建”它来实例化它,而是让Spring框架自动连接它,那么Spring将做任何必要的清理工作。是吗?还是在使用实体管理器后需要执行一些清理?

版本详情:

  • 雄猫8/Java8
  • Spring5.0.0.RELEASE
  • Spring Data Kay-RELEASE
  • 冬眠5.2.3.Final
  • 光2.4.5

任何建议或建议都将不胜感激,谢谢!

共有1个答案

葛高澹
2023-03-14

查询是什么?它很重吗?也许你这里有死锁?连接管理看起来很好。您没有显式获取连接,因此不需要释放它。查询可能运行很长时间,因此Hibernate无法完成它并释放连接。

此外,您可以检查数据库端打开的连接数。在那方面也做一些分析。

 类似资料:
  • 我正在尝试使用JPa连接到我的mysql数据库。 我生成了persistance.xml: 并且通过这样做,intelij生成了POJO类: 我已经创建了实体管理器,并希望从中获得结果: 和路线: 然而,当我导航到localhost:8080/hi 它抛出 在浏览器和 控制台中。我不知道什么会导致这个问题,非常感谢所有的帮助

  • 组织。springframework。jdbc。BadSqlGrammarException:PreparedStatementCallback;错误的SQL语法[从批处理作业实例中选择作业实例ID、作业名称,其中作业名称=?按作业实例ID描述排序];嵌套的例外是java。sql。SQLSyntaxErrorException:ORA-00942:表或视图不存在

  • 问题内容: 我有一个使用Java Servlet / JSP的应用程序。我的应用有多个客户端,但是每个客户端都有一个单独的数据库。所有数据库都具有相同的架构。我想确定用户登录系统时要使用哪个数据库连接。 例如,客户端A登录后,我确定客户端A属于数据库C,抓住了数据库C的连接,然后继续愉快地进行操作。 我正在将JPA与Hibernate一起用作我的JPA提供程序。是否可以使用多个持久性单元并在登录时

  • 本文向大家介绍使用Nodejs连接mongodb数据库的实现代码,包括了使用Nodejs连接mongodb数据库的实现代码的使用技巧和注意事项,需要的朋友参考一下 一个简单的nodejs连接mongodb示例,来自 mongodb官方示例 1. 创建package.json 首先,创建我们的工程目录connect-mongodb,并作为我们的当前目录 输入npm init命令创建package.j

  • 请知道,我对数据库很陌生。我能够正确安装mySQL和java连接器驱动程序。但每当我在eclipse中运行程序并尝试从我创建的数据库中检索信息时,我都会收到以下消息:“需要SSL连接,但服务器不支持”。下面是我要使用安全SSL连接运行的代码: `公共静态void main(字符串[]参数){

  • 问题内容: 我在Web应用程序中使用spring-boot,并使用spring- jpa从数据库中读取/写入数据库。它工作得很好,但是我想了解如何管理数据库连接。以下是我的数据库属性配置: 我已将最大连接数设置为500。当用户在我的spring应用程序上发出请求时,将为他打开数据库连接。完成请求后,spring jpa会关闭此连接吗?如果没有,它将何时关闭未使用的连接? 我已经阅读了http://