Wildfly连接池在取消的HTTP请求时耗尽

时间:2016-05-31 08:38:53

标签: java hibernate jpa wildfly connection-pooling

我在Wildfly 10上运行了一个运行RESTeasy和Hibernate的Java EE应用程序。应用程序非常简单,它有实体,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

[REMOVED]

更新2

上次更新(取消的HTTP请求)具有误导性:进一步的测试显示在其他情况下如何发生这种情况,例如计划任务(Java EE @Schedule)和事件观察者(Java EE @Observe)。

更新的问题是:当仅使用JPA访问数据库时,有什么可能阻止连接被释放?

1 个答案:

答案 0 :(得分:0)

最后发现它是什么:Java 8并行流在惰性集合上。简单地不要将并行流用于JPA关系的集合,因为它可以在流处理期间使用来自池的多个连接,但是在收集结果时,只有一个连接返回到池,而其他连接在尝试返回时失败相同的连接两次,最终耗尽了游泳池。