Mysql
 sql >> Base de données >  >> RDS >> Mysql

La fermeture d'un ensemble de résultats de streaming (à l'aide de mysql jdbc) prend beaucoup de temps

Donc, comme indiqué dans mon commentaire à la question, la réponse officielle du connecteur MySQL est que vous devez diffuser tout le jeu de résultats pour qu'il se ferme (http://dev.mysql.com/doc/refman/5.5/en/connector-j- reference-implementation-notes.html ). De plus, vous ne pouvez plus effectuer de requêtes pendant qu'un résultat de diffusion est en cours.

En tant que hack complètement dégoûtant, j'ai utilisé la réflexion pour descendre dans RowDataDynamic (ver. 5.1.24) et simulez une exception interrompue, comme ceci :

    final Class<?> rdClass = rd.getClass();
    final Field isInterruptedField = rdClass.getDeclaredField("isInterrupted");
    isInterruptedField.setAccessible(true);  // override 'protected' visibility
    isInterruptedField.set(rd, true);

Notez que vous devrez parcourir n'importe quel objet sur lequel vous avez une poignée pour accéder au ResultSet. Pour moi, j'utilisais la classe ScrollableResults d'Hibernate. Cela signifiait obtenir la référence ResultSet à partir de celui-ci (sa super classe, en fait), puis RowData à partir de là.

Cela permettra à l'opération de fermeture d'avoir lieu sans diffuser le reste des résultats CEPENDANT J'obtiens une exception en raison d'une taille de paquet non concordante lorsque j'essaie d'annuler la transaction (que je viens d'attraper et d'ignorer). En utilisant Atomikos comme pool de connexions, je verrai des avertissements concernant les prochaines connexions au fur et à mesure que les choses seront nettoyées, mais tout fonctionne toujours correctement.

Il est clair que cette approche peut ne pas fonctionner pour tout le monde, mais au moins c'est une solution de contournement lors du traitement via la requête de base de données ou de l'écriture d'une logique plus compliquée pour récupérer les résultats par lots ne fonctionnera tout simplement pas.