Leak of database connections with ThreadLocal when inspecting a Hibernate entity inside a ParallelStream

1

The problem is that when I inspect the attributes of an entity (Hibernate) inside a ParallelStream, sessions are created to the database in each Thread created by the Stream. These sessions can not be closed since I can not access the session. created by each internal Thread of the Stream, this causes a leak of sessions that eventually ends in the connection pool running out of connections to the database since the sessions opened by the Threads are not closed and therefore can not be reuse.

The environment is a Backend application mounted on a web container (Jetty), basically the ThreadLocal is used to store the connection session to the database for the duration of the client's HTTPRequest request, as the web container creates a Thread to respond to each HTTP request then the connection session to the database is stored in this ThreadLocal so that I always reuse this session at any point as long as it is the same Thread.

public class PoolConexiones {
    private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    ...
}

To get the session (connection to the Hibernate bd) I only call

Session sesion = PoolConexiones.threadLocal.get();

And then I can use the session to open the connection, create a transaction, make queries etc. and then close the session so that it returns to the pool in standby mode and is reused by the following HTTPRequest request

Entidad entidad = EntidadDAO.findById(1);

entidad.getHijos()
    .parallelStream() // <- el problema es cuando uso parallelStream en lugar de stream
    .map(hijo -> hijo.getNietos())
    .collect(Collectors.toCollection(ArrayList::new));

sesion.close();

Java ParallelStream what it does is to improve the processing performance of the Stream when processing it in parallel using threads, eye these threads are created in addition to the thread that processes the HTTPRequeest request therefore they are not managed by me, if in the stream I access to an attribute of an entity related to another entity using FetchMode = Lazy, this causes Hibernate to query the database but possibly being in another Thread this creates a new hibernate session in its own ThreadLocal to consult in the base of data the information of said attribute, if I do not have access to those ThreadLocal as I do to close the session?

The problem is that the original session opened when making the query with the DAO is normally closed in the last line but the sessions created internally in the parallelStream remain open which causes a leak of sessions and at the end the pool remains no sessions and the system collapses.

Using a normal stream without parallelization everything is fine, but I have to improve the performance of the process and for that I want to process the stream in parallel, any suggestion of how I can manage the sessions of the pool when using a ParallelStream?

    
asked by Carlos Lucero 02.03.2017 в 22:48
source

0 answers