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.
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.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
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:
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.
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.
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.