JDBC MySQL Problème de Connexion - Tentative de reconnexion 3 fois. Abandonner

J'ai un reste de l'application de service de l'exécution de l'Java framework Spring. L'application dépend d'un raccordement à une source externe de bases de données MySQL, qui est connecté via JDBC.

Mon problème est le maintien d'un lien solide entre le reste du service et de la db MySQL. J'ai ce que je considère un rudimentaire connexion failsafe en place qui ressemble à quelque chose comme:

public Connection getConnection() throws SQLException {
    if(connection == null){
         this.buildConnection();
    }
    else if(!connection.isValid(10)){ //Rebuild connection if it is no longer valid
        connection.close();
        this.buildConnection();
    }
    return connection;
}

À l'aide de cette méthode doit s'assurer que la connexion est valide avant toute requête est exécutée. Mon problème est que je périodiquement obtenez une exception lors de l'appel de cette méthode:

Ne pouvait pas créer une connexion au serveur de base de données. Tentative de reconnexion 3 fois. D'abandonner. SQLState: 08001. ErrorCode: 0.

Les choses qui m'ont super perplexe à ce sujet sont:

  1. Cette erreur ne se produit périodiquement. De nombreuses fois la connexion fonctionne tout simplement trouver.
  2. Je test cette même application sur mon ordinateur du développeur et cette erreur ne se produit jamais.

J'ai configuré la base MySQL sur mon propre serveur, donc je contrôle toutes ses options de configuration. À partir de cela, je sais que ce problème n'est pas lié au nombre maximum de connexions autorisées, ou un délai d'attente de connexion.

Édition - Mise À Jour 1:

  • Ce service est hébergé dans le Cloud de Service sur la plateforme Azure de Microsoft.
  • J'ai accidentellement mis en place comme un exemple dans le Nord de l'Europe, alors que la DB est situé en Amérique du Nord, probablement pas lié, mais en essayant de peindre l'ensemble de l'image.
  • Essayé les conseils à ce lien, sans succès. Pas en utilisant des pools de threads, et tous les jeux de résultats et les Déclarations/PreparedStatements sont fermées après.

Édition - Mise À Jour 2

Après quelques refontes, j'ai été en mesure de mettre en œuvre avec succès un HikariCP Pool de Connexion comme indiqué par @M. Deinum ci-dessous. Malheureusement, le même problème persiste. Tout fonctionne très bien sur ma machine locale, et tous les Tests Unitaires passent, mais dès que je la pousse d'Azur et d'attendre plus de quelques minutes entre les demandes, je reçois cette erreur, lorsque vous essayez de récupérer une connexion à partir de la piscine:

springHikariCP - Connexion n'est pas disponible, la demande dépassé après 38268ms. SQLState: 08S01. ErrorCode: 0.

Mon HikariCP configuration est comme suit:

//Set up connection pool
HikariConfig config = new HikariConfig();
config.setDriverClassName("com.mysql.jdbc.Driver"); 
config.setJdbcUrl("jdbc:mysql://dblocation");

//Connection pool properties
Properties prop = new Properties();
prop.setProperty("user", "Username");
prop.setProperty("password", "Password");
prop.setProperty("verifyServerCertificate", "false");
prop.setProperty("useSSL","true");
prop.setProperty("requireSSL","true");
config.setDataSourceProperties(properties);

config.setMaximumPoolSize(20);
config.setConnectionTestQuery("SELECT 1");
config.setPoolName("springHikariCP");
config.setLeakDetectionThreshold(5000); 

config.addDataSourceProperty("dataSource.cachePrepStmts", "true");
config.addDataSourceProperty("dataSource.prepStmtCacheSize", "250");
config.addDataSourceProperty("dataSource.prepStmtCacheSqlLimit", "2048");
config.addDataSourceProperty("dataSource.useServerPrepStmts", "true");

dataSource = new HikariDataSource(config);

Toute aide serait grandement appréciée.

Pourquoi n'utilisez vous pas un pool de connexion avec une requête de validation et de certains de reconnexion automatique caractéristiques? On dirait que vous essayez de pirater autour de vous.
Je n'ai pas de bonne raison pour laquelle je ne suis pas en utilisant des pools de threads (encore obtenir mes pieds sous moi avec JDBC), mais de ce que j'ai lire, autoreconnect avec MySQL n'est pas fiable. Le connection.isValid(int) méthode est fiable à partir de ce que je sais. Votre commentaire implique que l'utilisation d'un pool de connexion pourrait potentiellement éliminer les détails de bas niveau comme celui - ci- est-ce le cas?
Oui. Aussi, selon le pool de connexion, vous pouvez utiliser une requête de il utilise est valide (je recommande HikariCP que d'une piscine). Ce qui devrait supprimer automatiquement de connexion non valide à partir de la piscine de la création de nouvelles en cas de besoin. Par conséquent, vous n'avez pas vraiment besoin de reconnexion automatique juste une bonne piscine
Vous ne devriez pas être à l'aide du pilote/jdbcurl combo, mais la source de données de la classe à la place (comme il est expliqué sur le wiki de HikariCP) c'est vraiment que de la manière recommandée. (Je vais modifier ma réponse avec vos paramètres. Une chose à noter est que HikariDataSource s'étend HikariConfig vous permet d'économiser un peu de code.
Aussi pour la requête de test utiliser /* ping */ select 1 de juste /* ping */ comme qui va déclencher une commande ping au lieu de l'exécution de la requête. Peut varier un peu de comportement.

OriginalL'auteur JackB | 2016-02-02