首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >H2 - Tomcat jdbc连接池在达到最大限制后不回收连接

H2 - Tomcat jdbc连接池在达到最大限制后不回收连接
EN

Stack Overflow用户
提问于 2018-05-05 04:42:35
回答 1查看 768关注 0票数 0

问题陈述

我们在嵌入式模式下使用H2已经有一段时间了。它上面配置了一个连接池。以下是当前池配置:

代码语言:javascript
复制
h2.datasource.min-idle=10
h2.datasource.initial-size=10
h2.datasource.max-active=200
h2.datasource.max-age=600000
h2.datasource.max-wait=3000
h2.datasource.min-evictable-idle-time-millis=60000
h2.datasource.remove-abandoned=true
h2.datasource.remove-abandoned-timeout=60
h2.datasource.log-abandoned=true
h2.datasource.abandonWhenPercentageFull=100

H2配置:

代码语言:javascript
复制
spring.h2.console.enabled=true
spring.h2.console.path=/h2
h2.datasource.url=jdbc:h2:file:~/h2/cartdb
h2.server.properties=webAllowOthers
spring.h2.console.settings.web-allow-others=true
h2.datasource.driver-class-name=org.h2.Driver

*跳过用户名和密码属性。

我们已经通过记录池属性验证了上述配置是否生效。

这种设置的问题是,我们观察到定期(尽管是间歇性的)连接池耗尽,一旦连接池达到最大限制,它就会开始为某些查询抛出以下异常。

执行SqlExceptionHelper.logExceptions(SqlExceptionHelper.java:129) -

-apr-8080-exec-38超时:池为空。无法在3秒内获取连接,无可用大小:200;忙:200;空闲:0;上次等待:3000。

此后,即使在我们重新启动web服务器(在本例中为tomcat)之前的许多小时后,它也无法从该状态恢复。

H2驱动程序依赖关系:

代码语言:javascript
复制
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.196</version>
    <scope>runtime</scope>
</dependency>

查询模式和吞吐量

我们使用h2为每个请求加载一些数据,然后执行几个(大约50个) SELECT查询,最后删除数据。这导致在h2上(根据新的遗迹监控)每分钟(非工作时间除外)有一致的30k-40k调用。

每个读操作都会获取一个新的连接,并在执行后释放该连接。

代码语言:javascript
复制
EntityManager entityManager = null;
try {
     entityManager = entityManagerFactory.createEntityManager();
     Query query = entityManager.createNativeQuery(sqlQuery);
     query.setParameter("cartId", cartId);
     List<String> resultList = query.getResultList();
     return resultList;
} finally {
         if(null != entityManager) { entityManager.close(); }
}

Observations

  • 在应用程序重新启动后,池利用率一直处于最低水平,直到某个时刻,池利用率突然飙升并最终达到最大限制。这种情况会在1-2天内发生。与返回的连接计数相比,一旦池达到最大连接限制,借用的连接计数就会以更快的速度增加。
  • 同时,放弃的连接计数也会随着放弃连接计数的增加而开始增加。查询响应时间在池耗尽后保持不变。这样就排除了慢查询。
  • 这个问题甚至发生在流量最小的最奇怪的时候。因此它与流量无关。

请指引我们正确的方向来解决这个问题。

更新

最近,当一个这样的事件发生时,我们在堆栈跟踪中发现了以下原因:

由:org.h2.jdbc.JdbcSQLException引起的

:数据库可能已在使用: null。可能的解决方案:关闭所有其他连接;使用服务器模式90020-196

原因:根文件被锁定:nio:/ java.lang.IllegalStateException:The /h2/cartdb.mv.db 1.4.196/7

原因: java.nio.channels.OverlappingFileLockException

因此,在深入研究这一点之后,我们决定转到内存模式,因为我们不需要将数据持久化到应用程序的生命周期之外。因此,不应发生文件锁定,从而减少或消除此问题。

在任何一种情况下都会回来并更新。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-04 02:31:38

自上次更新问题以来:

在观察了相当长一段时间的性能后,我们得出结论,在文件模式(嵌入式)下使用H2以某种方式导致了周期性的文件锁异常(尽管是不规则的)。

由于我们的应用程序不需要将数据持久化到应用程序的生命周期之外,因此我们决定转到纯内存模式。

尽管文件锁异常的奥秘仍需揭开。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50182794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档