0

I am using the standard HikariCP implementation with the latest SpringBoot application. The scenario is like this. A call is made to my API that takes something from DB and after that calls another microservice. By default, the HikariCP has a pool of 10. The call to the internal microservice can take up to 20 minutes to respond. Scenario:

External Client -> MyApi -> SomeMicroService <- reponse time 20 minutes.

If I have 11 requests in parallel I have a problem because I receive:

HikariPool-1 - Connection is not available, request timed out after 30000ms

Why? Because the connection is returned to the pool after the session is closed.

Is there a way to close the connection after the DB call is made? If in one session we have 10 JPA requests is using the same connection but if you have 30 calls in parallel 10 will be ok and 20 will end up with the error.

I know that I can increase the pool from 10 to 100 but is there any other solution. @Transaction is not working. The connection is remaining open until the request is resolved one way on another.

So my question is: How to release the connection after DB request/response is made and create another one when it needs.

I'm using SpringBoot, SprinJPA, hibernate with default configurations.

Thanks in advance.

CostelD
  • 123
  • 1
  • 1
  • 7
  • I guess that `SomeMicroService` is the same instance, if so maybe [@EnableTask](https://spring.io/projects/spring-cloud-task) can help here. – robert Apr 03 '21 at 20:37
  • @robert - The second MS is on another machine on another network. – CostelD Apr 04 '21 at 07:49
  • Well, sure there's a way. Don't wrap the internal microservice call in a transaction together with the local DB access call. Connections are generally returned to the pool when transactions end and the connection is idle. – crizzis Apr 04 '21 at 09:13
  • Yes, true @crizzis . I need to incrase the time out up to 20 minutes and 40 seconds and idle to 30 seconds ( default is 10 minutes ) and should work however the 11 request it will be resolved after 40 minutes and 40 seconds if the worst scenario is happends. – CostelD Apr 04 '21 at 21:18
  • If you mean `idleTimeout`, then I believe this property represents the time after an idle connection is **destroyed**, not returned back to the pool (as a way of *scaling the pool down* when your app requires very few active connections). You should really just have three method calls `transactionalOne(); fetchDataFromExternalApi(); transactionalTwo()`. Make sure `TransactionSynchronizationManager.isActualTransactionActive()` returns `false` from inside the 'middle' method – crizzis Apr 05 '21 at 09:12
  • @crizzis - The problem is not related to transactional. The problem is that for each request the system book a connection from the connection pool and that connection is released when the session is ended. I tried your approach and is not working. However, using an Executor with Callable is working fine. In that Callable, I make my JPA request and the connection is blocked while that thread is making the JPA request and released imediatily. – CostelD Apr 07 '21 at 19:08
  • My understanding is that connection handling is [absolutely related to transactional](https://stackoverflow.com/a/27615246/1092818). Thus, if a finished transaction does not result in returning the connection to the pool, and you're not using `@PersistenceContext(type = EXTENDED)`, then this sounds like a resource leak. Perhaps I'm mistaken, though – crizzis Apr 07 '21 at 20:06

0 Answers0