java Wildfly连接池在被取消的HTTP请求上耗尽
我有一个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请求)有误导性:进一步的测试显示了这在其他情况下是如何发生的,比如计划任务(JavaEE@Schedule
)和事件观察者(JavaEE@Observe
)
最新的问题是:当使用JPA只访问数据库时,什么会阻止连接被释放
# 1 楼答案
终于找到了答案:惰性集合上的Java 8并行流。简单地说,不要使用并行流来收集JPA关系,因为在流处理期间,它可能会使用来自池的多个连接,但在收集结果时,只有一个连接返回到池,而其他连接失败,尝试两次返回同一连接,最终耗尽池