![](/img/trans.png)
[英]Springboot JPA Repository not releasing Hikari DB Connection
[英]trying to find db connection leak in my code, using Spring / JPA / Hikari
我有一個Spring Web應用程序的問題,它定期遇到從我的連接池獲取連接時出錯。 最后在日志中我看到如下條目:
只有恢復的方法我發現它一旦遇到這一點就重啟Tomcat。
我認為最可能的解釋是我在某處某些代碼沒有正確清理它的連接 - 將其返回給Hikari,留下一些東西讓Spring無法清理它等等。
要解決問題,我已將hikari配置leakDetectionThreshold設置為5000毫秒並啟用了日志記錄。 之后,我看到日志條目如
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 :: getPagedMappedDbResults方法,相關位包括在這里:
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對象,設置一些參數,並運行它來獲得一些結果。
當我完成它時,我是否需要使用Query對象? q.cleanup()? 我從閱讀文檔中看不到這樣的東西,但是我沒有在這個資源上做好管家嗎?
entityManager本身是從@Autowired注釋創建的。 我的理解是,如果我沒有“新”它來實例化它,而是讓Spring框架自動裝配它,那么Spring將做任何必要的清理工作。 是對的嗎? 或者在使用entityManager后是否需要進行一些清理?
版本細節:
任何建議或建議將不勝感激,謝謝!
什么是查詢? 它很重嗎? 也許你在這里遇到僵局? 連接管理看起來很好。 您沒有明確獲取連接,因此無需釋放它。 查詢可能會長時間運行,因此Hibernate無法完成它並釋放連接。
此外,您可以檢查數據庫端的打開連接數。 在這方面做一些分析。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.