【发布时间】:2016-09-29 04:14:12
【问题描述】:
我有一个 Java EE 应用程序在 Wildfly 10 上运行,带有 RESTeasy 和 Hibernate。该应用程序非常简单,它包含实体、DAO 和资源:
@Entity
public class MyEntity {
// ...
}
@Stateless
public class MyDAO {
@PersistenceContext
private EntityManager em;
public List<MyEntity> list() {
return this.em.createQuery("select e from MyEntity e", MyEntity.class).getResultList();
}
}
@Path("/resource")
public class MyResource {
@Inject
private MyDAO dao;
@GET
public List<MyEntity> get() {
return this.dao.list();
}
}
所以我不直接使用任何 JDBC 连接,我将其全部委托给 JPA。
问题是:无论我的连接池有多大,它最终都会耗尽。由于数据源连接是在无状态 bean 中处理的,因此应该无缝处理 AFAIK 连接打开/关闭。
调查这个连接泄漏,我发现我有很多
ERROR [io.undertow.request] (default task-25) UT005023: Exception handling request to /resource: org.jboss.resteasy.spi.UnhandledException: RESTEASY003770: Response is committed, can't handle exception
...
Caused by: java.io.IOException: Broken pipe
异常,由客户端取消的 HTTP 请求引起。这些异常会产生连接泄漏吗?我希望不会,因为客户端操作不应耗尽服务器连接池。
问题是:问题可能是被取消的 HTTP 请求,我如何指示 Undertow/RESTeasy/Hibernate 处理并干净地退出?还有哪里可能是泄漏或我如何进行调查以找出答案?
更新 1
[已移除]
更新 2
最后一次更新(取消的 HTTP 请求)具有误导性:进一步的测试表明在其他情况下会发生这种情况,例如计划任务 (Java EE @Schedule) 和事件观察器 (Java EE @Observe)。
更新后的问题是:当仅使用 JPA 访问数据库时,什么会阻止连接被释放?
【问题讨论】:
-
如果你只是让连接池更大,你给数据库服务器更多的工作。它可以处理更多的连接,但同时由于负载,每个操作需要更多的时间才能完成。
-
请添加
MyDAO#list()方法。 -
@Kayaman 谢谢你的提示,我实际上把连接池做得更大了,否则它很快就会耗尽。
-
@v.ladynev 完成,这是一个简单的 JPA 查询。
-
那么您是否做过任何事情来了解您的查询有多无效,您的交易是否太长,或者任何实际上重要的事情?是您的数据库工作量太大,还是您的代码效率很低?
标签: java hibernate jpa wildfly connection-pooling