dans le cas de l'utilisation de PreparedStatement avec une seule connexion commune sans pool, puis-je recréer une instance pour chaque opération dml / sql en conservant la puissance des instructions préparées?
Je veux dire:
for (int i=0; i<1000; i++) {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
preparedStatement.close();
}
au lieu de:
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i=0; i<1000; i++) {
preparedStatement.clearParameters();
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
}
preparedStatement.close();
ma question vient du fait que je veux mettre ce code dans un environnement multithread, pouvez-vous me donner quelques conseils? Merci
java
jdbc
prepared-statement
Plume d'acier
la source
la source
sql
ne change pas avec dans la boucle? si cette requête ne change pas pour chaque itération de la boucle, alors pourquoi en créez-vous une nouvellePreparedStatement
pour chaque itération (dans le premier extrait de code)? Y a-t-il une raison de le faire?Réponses:
La deuxième façon est un peu plus efficace, mais une bien meilleure façon est de les exécuter par lots:
Vous dépendez cependant de l'implémentation du pilote JDBC du nombre de lots que vous pouvez exécuter à la fois. Vous pouvez par exemple vouloir les exécuter tous les 1000 lots:
En ce qui concerne les environnements multithread, vous n'avez pas à vous en soucier si vous acquérez et fermez la connexion et l'instruction dans la plus courte portée possible à l'intérieur du même bloc de méthode selon l'idiome JDBC normal en utilisant l' instruction try-with-resources comme indiqué dans au-dessus des extraits.
Si ces lots sont transactionnels, vous souhaitez désactiver la validation automatique de la connexion et ne valider la transaction que lorsque tous les lots sont terminés. Sinon, cela peut entraîner une base de données sale lorsque le premier groupe de lots a réussi et le dernier non.
la source
inside the same method block
- vous voulez dire que chaque thread aura sa propre pile et que ces connexions et instructions sont dans la pile d'un côté et d'une autre source de données donnera à chaque nouvel appel de executeFunction (== chaque thread) une instance de connexion distincte. Dois-je vous comprendre bien? "La boucle dans votre code n'est qu'un exemple trop simplifié, non?
Il serait préférable de créer le
PreparedStatement
seul une fois, et de le réutiliser encore et encore dans la boucle.Dans les situations où cela n'est pas possible (car cela compliquait trop le déroulement du programme), il est toujours avantageux d'utiliser a
PreparedStatement
, même si vous ne l'utilisez qu'une seule fois, car le côté serveur du travail (analyse du SQL et mise en cache de l'exécution plan), sera toujours réduite.Pour résoudre la situation dans laquelle vous souhaitez réutiliser le côté Java
PreparedStatement
, certains pilotes JDBC (comme Oracle) ont une fonction de mise en cache: si vous créez unPreparedStatement
pour le même SQL sur la même connexion, il vous donnera le même (mis en cache ) exemple.À propos du multi-threading: je ne pense pas que les connexions JDBC puissent être partagées entre plusieurs threads (c'est-à-dire utilisées simultanément par plusieurs threads) de toute façon. Chaque thread doit obtenir sa propre connexion à partir du pool, l'utiliser et la renvoyer à nouveau au pool.
la source