我有一个JavaEE应用程序在Wildfly 10上运行,带有RESEasy和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/RESEasy/Hibernate处理该请求并干净地退出?泄漏可能在哪里,或者我如何调查以查明?
更新1
[删除]
更新2
上一次更新(已取消的HTTP请求)具有误导性:进一步的测试显示了这在其他情况下是如何发生的,例如计划任务(JavaEE
@Schedule
)和事件观察员(Java EE
@Observe
).
更新后的问题是:当只使用JPA访问数据库时,什么会阻止释放连接?