Quelle est la bonne manière de gérer les connexions JDBC avec le Printemps et DBCP?
Je suis en utilisant le Spring MVC pour construire une couche mince sur le dessus d'une base de données SQL Server. Quand j'ai commencé les essais, il semble qu'il ne gère pas de stress très bien :). Je suis en utilisant Apache Commons DBCP pour gérer la connexion de la mutualisation et de la source de données.
Quand j'ai d'abord tenté ~10-15 connexions simultanées, il sert à accrocher et je dois redémarrer le serveur (pour les dev, je suis en utilisant Tomcat, mais je vais avoir à déployer sur Weblogic finalement).
Ce sont mes Printemps bean définitions:
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="[...]"/>
<property name="username" value="[...]" />
<property name="password" value="[...]" />
</bean>
<bean id="partnerDAO" class="com.hp.gpl.JdbcPartnerDAO">
<constructor-arg ref="dataSource"/>
</bean>
<!-- + other beans -->
Et ce est la façon dont je les utilise:
//in the DAO
public JdbcPartnerDAO(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
//in the controller
@Autowired
private PartnerDAO partnerDAO;
//in the controller method
Collection<Partner> partners = partnerDAO.getPartners(...);
Après la lecture de autour de un peu, j'ai trouvé le maxWait
, maxActive
et maxIdle
propriétés de la BasicDataSource (à partir de GenericObjectPool). Ici vient le problème. Je ne suis pas sûr de savoir comment je doit les définir, en terme de performance. De ce que je sais, le Printemps devrait être la gestion de mes connexions, donc je ne devrais pas avoir à vous soucier de les libérer.
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="[...]"/>
<property name="username" value="[...]" />
<property name="password" value="[...]" />
<property name="maxWait" value="30" />
<property name="maxIdle" value="-1" />
<property name="maxActive" value="-1" />
</bean>
D'abord, j'ai mis maxWait
, afin qu'il ne traîne pas et, au lieu de lever une exception si aucune connexion n'est disponible à partir de la piscine. Le message était:
Ne pouvait pas obtenir la Connexion JDBC; nested exception est org.apache.commons.dbcp.SQLNestedException: Impossible d'obtenir une connexion, piscine erreur de Délai d'attente pour objet inactif
Il y a quelques requêtes de longue durée, mais la levée de l'exception, indépendamment de la complexité de la requête.
Ensuite, j'ai mis maxActive et maxIdle de sorte qu'elle ne jetez 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 l'ai mis à -1 il n'y a plus les exceptions levées et tout semble pour fonctionner correctement.
Considérant que cette application doit prendre en charge un grand nombre de requêtes simultanées est-il acceptable de laisser ces paramètres à l'infini? De Printemps réellement gérer mes connexions, en considérant les erreurs que j'ai été reçu? Devrais-je passer à C3P0 étant donné que c'est un peu mort?
J'ai mis à jour mon post avec le message d'exception et quelques informations supplémentaires.
OriginalL'auteur Alex Ciminian | 2010-08-19
Vous devez vous connecter pour publier un commentaire.
Comme vous l'avez déjà constaté, la valeur par défaut dbcp pool de connexion est de 8 connexions, donc si vous voulez exécuter 9 requêtes simultanées l'un d'eux sera bloqué. Je vous suggère de vous connecter à votre base de données et exécuter
exec sp_who2
qui va vous montrer ce qui est connecté et actif, et si des requêtes sont bloqués. Vous pouvez alors confirmer si le problème est sur la db ou dans votre code.Aussi longtemps que vous utilisez le Printemps JdbcTemplate de la famille des objets de vos connexions seront gérés comme vous vous attendez, et si vous voulez utiliser le raw d'une source de données, assurez-vous d'utiliser DataSourceUtils pour obtenir une Connexion.
Une autre suggestion - avant le Printemps 3, ne jamais utiliser de JdbcTemplate, s'en tenir à SimpleJdbcTemplate, vous pouvez toujours accéder aux mêmes méthodes à l'aide de SimpleJdbcTemplate.getJdbcOperations(), mais vous devez trouver vous-même écrire beaucoup mieux le code à l'aide de médicaments génériques, et de supprimer la nécessité de toujours créer JdbcTemplate/NamedParameterJdbcTemplate instances.
OriginalL'auteur Jon Freedman
DBCP
maxWait
paramètre doit être défini en millisecondes.30
ms est très faible valeur, pensez à augmenter à30000
ms et essayez de nouveau.OriginalL'auteur stoweesh
Nous allons changer le point de vue.
Il pourrait être parce que la table ou les enregistrements dans la table, qui sont à interroger a été verrouillé (par certains autres actifs de transaction) et donc il expire.
Essayez d'exécuter la même requête de sql server Client et si elle prend un long moment, puis vous pouvez être sûr que c'est la table ou de verrouillage d'enregistrement qui en est la cause.
maxActive
etmaxIdle
paramètres de la source de données d'une grande valeur (ou à l'infini). Cela m'amène à penser que la question est à partir de la ConnectionPool, comme le message de l'exception unis.OriginalL'auteur Kingsly