web-dev-qa-db-fra.com

HikariCP Connexions inactives restant dans le pool de connexions en tant que actives

J'utilise Spring Boot (1.5.6), Hibernate, Postgres, Hikari (2.7.8). Ma configuration est:

spring.datasource.hikari.minimumIdle=1
spring.datasource.hikari.maximumPoolSize=20
spring.datasource.hikari.idleTimeout=30000
spring.datasource.hikari.poolName=SpringBootJPAHikariCP
spring.datasource.hikari.maxLifetime=50000
spring.datasource.hikari.connectionTimeout=30000

Ce que je pense, c’est que les connexions inactives devraient être libérées après 30000 ms/30 secondes d’inactivité.
Le problème est qu’à chaque requête, une nouvelle connexion est établie en laissant toute la connexion inactive en l’état. Donc, après quelques fois, je me retrouve avec 20 connexions inactives et avec une nouvelle requête, Hikari essaie d’obtenir une nouvelle connexion et d’obtenir SpringBootJPAHikariCP - Connection is not available, request timed out after 30001ms.

Alors, qu'est-ce que je fais mal? Ou avez-vous mal compris la configuration?

Journal d'initialisation Hikari: 

SpringBootJPAHikariCP - configuration:
 allowPoolSuspension.............false
 autoCommit......................true
 catalog.........................none
 connectionInitSql...............none
 connectionTestQuery.............none
 connectionTimeout...............30000
 dataSource......................none
 dataSourceClassName.............none
 dataSourceJNDI..................none
 dataSourceProperties............{password=<masked>}
 driverClassName................."org.postgresql.Driver"
 healthCheckProperties...........{}
 healthCheckRegistry.............none
 idleTimeout.....................30000
 initializationFailFast..........true
 initializationFailTimeout.......1
 isolateInternalQueries..........false
 jdbc4ConnectionTest.............false
 jdbcUrl.........................jdbc:postgresql://localhost:5432/dbname
 leakDetectionThreshold..........0
 maxLifetime.....................50000
 maximumPoolSize.................20
 metricRegistry..................none
 metricsTrackerFactory...........none
 minimumIdle.....................1
 password........................<masked>
 poolName........................"SpringBootJPAHikariCP"
 readOnly........................false
 registerMbeans..................false
 scheduledExecutor...............none
 scheduledExecutorService........internal
 schema..........................none
 threadFactory...................internal
 transactionIsolation............default
 username........................"postgres"
 validationTimeout...............5000

Mise à jour: Au cours des dernières 24 heures, j'ai essayé plusieurs solutions à partir de threads différents et aucune d'entre elles n'a résolu mon problème. Voici donc les observations qui pourraient être importantes. 

  1. SpringBootJPAHikariCP - Reset (autoCommit) on connection org.postgresql.jdbc.PgConnection@1344bbf1 a trouvé ce journal. étudiée Réinitialiser (autoCommit) à la connexion dans HikariCP ce fil. essayé de mettre auto commit même (vrai) des deux côtés (hibernate et Hikari) et essayé avec faux des deux côtés également. toujours pas de chance.
  2. Active leakDetectionThreshold, obtient une exception de détection de fuite. Nous avons donc essayé de comprendre si le gestionnaire de transactions en veille prolongée/spring libérait des connexions. D'après les journaux ci-dessous, il semble que le fonctionnement en hibernation fonctionne bien. 

    28 22:19:35- DEBUG - o.s.orm.jpa.JpaTransactionManager-371 ::  Opened new EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@4212be39] for JPA transaction
    28 22:19:35- DEBUG - o.h.e.t.internal.TransactionImpl-51 ::  begin
    28 22:19:35- DEBUG - o.s.orm.jpa.JpaTransactionManager-403 ::  Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@243e942]
    2com.someentity.MyEntity#ac918eed-345f-4a6c-8539-fe14e7fc41e2
    28 22:19:35- DEBUG - o.h.r.j.i.LogicalConnectionManagedImpl-137 ::  Initiating JDBC connection release from afterTransaction
    28 22:19:35- DEBUG - c.zaxxer.hikari.pool.ProxyConnection-242 ::  SpringBootJPAHikariCP - Executed rollback on connection org.postgresql.jdbc.PgConnection@1344bbf1 due to dirty commit state on close().
    28 22:19:35- DEBUG - o.h.e.i.AbstractFlushingEventListener-132 ::  Processing flush-time cascades
    28 22:19:35- DEBUG - o.h.e.i.AbstractFlushingEventListener-174 ::  Dirty checking collections
    
    28 22:19:35- DEBUG - org.hibernate.internal.SessionImpl-508 ::  Disconnecting session
    28 22:19:35- DEBUG - o.s.orm.jpa.JpaTransactionManager-759 ::  Initiating transaction commit
    28 22:19:35- DEBUG - o.s.orm.jpa.JpaTransactionManager-512 ::  Committing JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@4212be39]
    28 22:19:35- DEBUG - o.h.e.t.internal.TransactionImpl-62 ::  committing
    28 22:19:35- DEBUG - o.h.r.j.i.LogicalConnectionManagedImpl-137 ::  Initiating JDBC connection release from afterTransaction
    28 22:19:35- DEBUG - o.h.r.j.i.LogicalConnectionManagedImpl-137 ::  Initiating JDBC connection release from afterTransaction
    28 22:19:35- DEBUG - o.s.orm.jpa.JpaTransactionManager-600 ::  Closing JPA EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@4212be39] after transaction
    28 22:19:35- DEBUG - o.s.o.jpa.EntityManagerFactoryUtils-435 ::  Closing JPA EntityManager
    
  3. Toutes les connexions inactives sont idle forme postgres point de vue et active forme point de vue Hikari. Donc, quand il y a 5 connexions inactives de la base de données, il y a toatal = 5, active=4, idle = ,waiting=0 dans le journal Hikari.

Remarque: 

  1. peut-être que j'ai ce problème exact https://github.com/brettwooldridge/HikariCP/issues/109 dans mon cas, la connexion active augmente avec chaque transaction.

  2. HikariCP - la connexion n'est pas disponible il s'agit également du même problème. mais personne ne fournit de solution claire à cela. btw j'utilisais @Transactional de la mendicité comme suggéré par la réponse acceptée. 

6
Saif

Ce n'était pas un problème Hikari, il y avait une erreur de mon côté. Nous affichons toujours les détails de la raison pour laquelle cela s’est produit, au cas où cela aiderait quelqu'un.

J'utilisais spring boot 1.5.6 (c'était la dernière version quand j'ai commencé à travailler) . Cette version incluait spring-orm 4.3.1. Cette version de spring-orm incluait la prise en charge de trois versions de hibernate, Hibernate5, Hibernate4 et Hibernate3.

J'ai donc configuré Spring Boot avec la configuration ci-dessous pour current_session_context_class.

spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext

Tout fonctionnait bien jusqu'à la gestion des connexions de Hikari. Ce qui est arrivé est spring-boot-starter-jpa pour 1.5.6 inclus Hibernate5 (je veux dire noyau hibernate).

Donc, après avoir exécuté une opération de base de données, le printemps perd le contrôle de cette connexion (possibilité de non concordance de cette version). D'où le problème.

Après avoir changé 

org.springframework.orm.hibernate4.SpringSessionContext

à 

org.springframework.orm.hibernate5.SpringSessionContext

le problème a été résolu immédiatement.

Ma configuration actuelle est

spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL95Dialect

Pour votre information, après la résolution du problème, vous passez à Spring Boot 2. 

2
Saif