When a spring boot request starts, it obtains a connection from the pool. My question is - is this connection remains tied to the request thread (even if it is not executing any query) and only returned to the pool when request completes?
For example, if I'm doing something like:
Would the connection obtained by this request thread remain occupied with the thread (and not available to other requests) for 20ms or 1520ms?
PS: I'm using Spring Boot 2.0 with HikariCP and I'm not using @Transactional.
Thanks.
If you have Spring MVC on your classpath, Spring will configure an instance of OpenEntityManagerInViewInterceptor
automatically (in org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.JpaWebConfiguration
), unless you configure spring.jpa.open-in-view
to false. This interceptor will open an instance of EntityManager
and bind it to the TransactionSynchronizationManager
for the whole duration of the request.
What that means is that at the first use of a repository query, it will borrow a connection from the pool and keep it until the end of the request when the EntityManager
is closed by the interceptor. It's the EntityManager
's responsibility to return the connection to the pool. So, in that case, the connection will be borrowed for 1520ms in your example.
If you disable the spring.jpa.open-in-view
option, a connection will be borrowed and returned at each use of a repository query given you don't use any explicit transaction. While this may look better, you have to keep in mind that managed instances of your entities will need to be reattached systematically on each persist operation so it may be costly. You will also loose the benefits of the EntityManager
caching. To avoid this, use transactions to read/modify/persist your entities and avoid reattaching.
Finally, keep in mind that if you disable spring.jpa.open-in-view
, since you don't have an EntityManager
around for the duration of the request, you will need to make sure your lazy loaded relations are loaded inside a transaction otherwise you'll get the dreaded LazyInitializationException
.