代码之家  ›  专栏  ›  技术社区  ›  Giovanni Lovato

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

  •  0
  • Giovanni Lovato  · 技术社区  · 9 年前

    我有一个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访问数据库时,什么会阻止释放连接?

    1 回复  |  直到 9 年前
        1
  •  0
  •   Giovanni Lovato    8 年前

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