web-dev-qa-db-fra.com

Spring Boot JPA - configuration de la reconnexion automatique

J'ai une belle application Web Spring Boot JPA. Il est déployé sur Amazon Beanstalk et utilise Amazon RDS pour la persistance des données. Cependant, il n’est pas utilisé aussi souvent et échoue donc après un certain temps, avec ce genre d’exception:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: le dernier paquet reçu avec succès du serveur était de 79 870 633 millisecondes.
Le dernier paquet envoyé avec succès au serveur était de 79 870 634 millisecondes. est plus long que la valeur configurée par le serveur 'wait_timeout'. Vous devez envisager l'expiration et/ou le test de la validité de la connexion avant utilisation dans votre application, en augmentant les valeurs configurées par le serveur pour les délais d'attente du client ou en utilisant la propriété de connexion Connector/J 'autoReconnect = true' pour éviter ce problème.

Je ne sais pas comment configurer ce paramètre et ne trouve aucune information à ce sujet sur http://spring.io (un très bon site cependant). Quelles sont quelques idées ou des pointeurs d'information?

90
stoffer

Je suppose que le démarrage configure la DataSource pour vous. Dans ce cas, et puisque vous utilisez MySQL, vous pouvez ajouter ce qui suit à votre application.properties jusqu’à 1,3

spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1

Comme djxak l'a noté dans le commentaire, les versions 1.4+ définissent des espaces de noms spécifiques pour les quatre pools de connexions pris en charge par Spring Boot: Tomcat, hikari, dbcp, dbcp2 (dbcp est obsolète à partir de 1.5). Vous devez vérifier le pool de connexions que vous utilisez et vérifier si cette fonctionnalité est prise en charge. L'exemple ci-dessus concernait Tomcat, vous devez donc l'écrire comme suit dans la version 1.4+:

spring.datasource.Tomcat.testOnBorrow=true 
spring.datasource.Tomcat.validationQuery=SELECT 1

Notez que l'utilisation de autoReconnect est non recommandé :

L'utilisation de cette fonctionnalité n'est pas recommandée car elle a des effets secondaires liés à l'état de la session et à la cohérence des données lorsque les applications ne gèrent pas correctement les exceptions SQLExceptions. Elle est uniquement conçue pour être utilisée lorsque vous ne pouvez pas configurer votre application pour gérer les exceptions SQLExceptions résultant de connexions mortes et obsolètes correctement.

122
Stephane Nicoll

Les suggestions ci-dessus n'ont pas fonctionné pour moi . Ce qui a vraiment fonctionné est l'inclusion des lignes suivantes dans le fichier application.properties

spring.datasource.testWhileIdle = true
spring.datasource.timeBetweenEvictionRunsMillis = 3600000
spring.datasource.validationQuery = SELECT 1

Vous pouvez trouver l'explication sur ici

25
Soumya

Je viens de passer à Spring Boot 1.4 et j'ai trouvé que ces propriétés avaient été renommées:

spring.datasource.dbcp.test-while-idle=true
spring.datasource.dbcp.time-between-eviction-runs-millis=3600000
spring.datasource.dbcp.validation-query=SELECT 1
8
Jose Jurado

La définition de spring.datasource.Tomcat.testOnBorrow=true dans application.properties ne fonctionnait pas. 

Le réglage par programme comme ci-dessous a fonctionné sans problème. 

import org.Apache.Tomcat.jdbc.pool.DataSource;
import org.Apache.Tomcat.jdbc.pool.PoolProperties;    

@Bean
public DataSource dataSource() {
    PoolProperties poolProperties = new PoolProperties();
    poolProperties.setUrl(this.properties.getDatabase().getUrl());         
    poolProperties.setUsername(this.properties.getDatabase().getUsername());            
    poolProperties.setPassword(this.properties.getDatabase().getPassword());

    //here it is
    poolProperties.setTestOnBorrow(true);
    poolProperties.setValidationQuery("SELECT 1");

    return new DataSource(poolProperties);
}
7
whoami

J'ai le même problème. Spring 4 et Tomcat 8. Je résous le problème avec la configuration de Spring

<bean id="dataSource" class="org.Apache.Tomcat.jdbc.pool.DataSource" destroy-method="close">
    <property name="initialSize" value="10" />
    <property name="maxActive" value="25" />
    <property name="maxIdle" value="20" />
    <property name="minIdle" value="10" />
     ...
    <property name="testOnBorrow" value="true" />
    <property name="validationQuery" value="SELECT 1" />
 </bean>

J'ai testé. Ça marche bien! Cette deux ligne fait tout pour se reconnecter à la base de données:

<property name="testOnBorrow" value="true" />
<property name="validationQuery" value="SELECT 1" />
3
grep

La réponse de whoami est la bonne. En utilisant les propriétés suggérées, j’ai été incapable de le faire fonctionner (en utilisant Spring Boot 1.5.3.RELEASE)

J'ajoute ma réponse car il s'agit d'une classe de configuration complète, ce qui pourrait aider une personne utilisant Spring Boot:

@Configuration
@Log4j
public class SwatDataBaseConfig {

    @Value("${swat.decrypt.location}")
    private String fileLocation;

    @Value("${swat.datasource.url}")
    private String dbURL;

    @Value("${swat.datasource.driver-class-name}")
    private String driverName;

    @Value("${swat.datasource.username}")
    private String userName;

    @Value("${swat.datasource.password}")
    private String hashedPassword;

    @Bean
    public DataSource primaryDataSource() {
        PoolProperties poolProperties = new PoolProperties();
        poolProperties.setUrl(dbURL);
        poolProperties.setUsername(userName);
        poolProperties.setPassword(password);
        poolProperties.setDriverClassName(driverName);
        poolProperties.setTestOnBorrow(true);
        poolProperties.setValidationQuery("SELECT 1");
        poolProperties.setValidationInterval(0);
        DataSource ds = new org.Apache.Tomcat.jdbc.pool.DataSource(poolProperties);
        return ds;
    }
}
1
naoru

Si quelqu'un utilise DataSource personnalisé

@Bean(name = "managementDataSource")
@ConfigurationProperties(prefix = "management.datasource")
public DataSource dataSource() {
    return DataSourceBuilder.create().build();
}

Les propriétés devraient ressembler à ce qui suit. Notez le @ConfigurationProperties avec le préfixe. Le préfixe est tout ce qui précède le nom de la propriété

management.datasource.test-on-borrow=true
management.datasource.validation-query=SELECT 1

Une référence pour Spring Version 1.4.4.RELEASE

1
Justin

Comme certains l’ont déjà fait remarquer, spring-Boot 1.4+ dispose d’espaces de noms spécifiques pour les quatre pools de connexions. Par défaut, hikaricp est utilisé dans spring-boot 2+. Vous devrez donc spécifier le code SQL ici. La valeur par défaut est SELECT 1. Voici ce dont vous auriez besoin pour DB2 par exemple: spring.datasource.hikari.connection-test-query=SELECT current date FROM sysibm.sysdummy1  

Caveat : Si votre pilote prend en charge JDBC4, nous vous recommandons vivement de ne pas définir cette propriété. Cela concerne les pilotes "hérités" qui ne prennent pas en charge l'API JDBC4 Connection.isValid (). C'est la requête qui sera exécutée juste avant qu'une connexion ne vous soit donnée à partir du pool pour valider que la connexion à la base de données est toujours vivante. Là encore, essayez d’exécuter le pool sans cette propriété. HikariCP enregistrera une erreur si votre pilote n’est pas conforme à JDBC4 pour vous en informer. Par défaut: aucun

0
code4kix