7
votes

Quelle est la bonne façon de gérer les connexions JDBC avec le printemps et le DBCP?

J'utilise le Spring MVC pour construire une couche mince sur une base de données SQL Server. Quand j'ai commencé à tester, il semble que cela ne gère pas très bien le stress :). J'utilise Apache Commons DBCP pour gérer la mise en commun de la connexion et la source de données.

Lorsque je tente d'abord ~ ​​10-15 connexions simultanées, il était utilisé pour accrocher et je devrais redémarrer le serveur (pour que j'utilise Tomcat, mais je vais devoir déployer sur Weblogic éventuellement). < / p>

Ce sont mes définitions de haricot de printemps: xxx

et c'est comme ça que je les utilise: xxx

Après avoir lu environ un peu, j'ai trouvé le maxwait , Maxactive et Maxide Propriétés du BasicDataSource (de GenericObjectpool ). Voici le problème. Je ne sais pas comment je devrais les définir, la performance. D'après ce que je sais, le printemps devrait gérer mes connexions afin que je ne devrais pas avoir à craindre de les libérer. xxx

premier, je définis maxwait , de sorte qu'il ne se bloque pas et jette une exception lorsqu'aucune connexion n'était disponible auprès de la piscine. Le message d'exception était:

n'a pas pu obtenir une connexion JDBC; Exception imbriquée est org.apache.commons.dbcp.sqlnestexception: Impossible d'obtenir une connexion, le délai d'erreur de la piscine en attente de l'objet inactif

Il existe des requêtes de longue durée, mais l'exception a été lancée, quelle que soit la complexité de la requête.

Puis, j'ai défini Maxactive et Maxide afin qu'il ne jette pas les exceptions la première place. Les valeurs par défaut sont 8 pour Maxactive et MaxIdle (Je ne comprends pas pourquoi); Si je les ai mis à -1, il n'y a plus d'exceptions levées et que tout semble va bien fonctionner.

Considérant que cette application doit prendre en charge un grand nombre de demandes concomitantes, c'est bien laisser ces paramètres à infini? Spring va-t-il réellement gérer mes connexions, compte tenu des erreurs que je recevais? Dois-je passer à C3P0 Considérant qu'il est un peu mort?


2 commentaires

Si vous obtenez des exceptions, l'affichage de la StackTrace aidera à identifier le problème facilement, y a-t-il des requêtes de longue date où vous voyez les problèmes?


J'ai mis à jour mon message avec le message d'exception et quelques informations supplémentaires.


3 Réponses :


2
votes

changeons la perspective.

Mais l'exception a été lancée quelle que soit la complexité de la requête

Cela pourrait être dû au fait que la table ou les enregistrements dans la table, que vous interrogez-vous a été verrouillée (par une autre transaction active) et, par conséquent, il est temps de sortir.

Essayez d'exécuter la même requête à partir du client SQLServer et si cela prend une longue période, vous pouvez être sûr qu'il s'agit de la table ou du verrou d'enregistrement qui cause ceci.


1 commentaires

Je vois votre point, mais le problème disparaît complètement lorsque je définit le Maxactive et MaxIdle des paramètres de la source de données à une valeur importante (ou à infini). Cela me conduit à penser que le problème provient de la ConnectionPool, car le message d'exception indique.



6
votes

Comme vous l'avez déjà découvert, le pool de connexion DBCP par défaut est 8 connexions, donc si vous souhaitez exécuter 9 requêtes simultanées, l'une d'entre elles sera bloquée. Je vous suggère de vous connecter à votre base de données et d'exécuter exec sp_who2 qui vous montrera ce qui est connecté, actif et si toutes les requêtes sont bloquées. Vous pouvez ensuite confirmer si le problème est sur la DB ou dans votre code.

Tant que vous utilisez la famille d'objets JDbCtMapet de Springs de Springs, vos connexions seront gérées à votre guise. Si vous souhaitez utiliser une source de données RAW, assurez-vous d'utiliser DataSourceutils pour obtenir une connexion.

Une autre suggestion - avant le printemps 3, n'utilisez jamais JDBCTTEMPATE, collez-vous à SimpleJDBCTemplate, vous pouvez toujours accéder aux mêmes méthodes utilisant SIMPLEJDBCTTEMPLET.GETJDBCOPERATIONS () , mais vous devriez vous retrouver Écrire beaucoup plus de code plus agréable à l'aide de génériques et supprimer la nécessité de créer des instances JDBCTEPLEPLATE / NAMEDPARAMETJDBCTTELLATEDBLACE.


0 commentaires

9
votes

DBCP maxwait doit être défini en millisecondes. 30 MS est une très faible valeur, envisagez de l'augmenter à 30000 MS et réessayez.


0 commentaires