Je suis encore un étudiant de premier cycle juste travail à temps partiel et je suis toujours essayer d'être au courant de meilleures façons de faire les choses. Récemment, je devais écrire un programme pour le travail où le fil conducteur du programme engendrerait des fils « tâche » (pour chaque db enregistrement « tâche ») qui effectuer certaines opérations et mettre à jour le record de dire qu'il a terminé. Par conséquent, je besoin d'un objet de connexion de base de données et des objets PreparedStatement ou disponibles aux objets ThreadedTask.
est à peu près ce que je fini par écrire, est la création d'un PreparedStatement code> par thread un déchet? Je pensais que statique
PreparedStatments code> pourrait créer des conditions de course ... p>
public class ThreadedTask implements runnable {
private final PreparedStatement taskCompleteStmt;
public ThreadedTask() {
//...
taskCompleteStmt = Main.db.prepareStatement(...);
}
public run() {
//...
taskCompleteStmt.executeUpdate();
}
}
public class Main {
public static final db = DriverManager.getConnection(...);
}
3 Réponses :
Je crois que ce n'est pas une bonne idée de connexions de base de données d'actions (et déclarations préparées) entre les threads. JDBC ne nécessite pas de connexion pour être thread-safe, et je prévois que la plupart des pilotes de ne pas être. P>
Donner à chaque fil de sa propre connexion (ou synchronisez sur la connexion pour chaque requête, mais qui va à l'encontre probablement dans le but d'avoir plusieurs threads). P>
est la création et la destruction des objets PreparedStatement qui sont toujours les mêmes pas un énorme gaspillage? P> blockQuote>
Pas vraiment. La plupart des travaux se produit sur le serveur, et seront mises en cache et réutilisés là si vous utilisez la même instruction SQL. Certains pilotes JDBC prennent également en charge la mise en cache de l'instruction, de sorte que même la poignée de déclaration côté client peut être remploi. P>
Vous pourriez voir une amélioration substantielle en utilisant des requêtes au lieu de par lots (ou en plus) plusieurs threads, cependant. Préparer la requête une fois, et l'exécuter pour un grand nombre de données dans un seul grand lot. P>
Vous êtes mieux d'utiliser un pool de connexion et d'obtenir chaque fil pour demander une connexion de la piscine. Créez vos déclarations sur la connexion que vous êtes remis, ne pas oublier de le fermer et ainsi libérer à la piscine lorsque vous avez terminé. L'avantage d'utiliser la piscine est que vous pouvez facilement augmenter le nombre de connexions disponibles si vous trouvez que la concurrence fil devient un problème. P>
Le threadsafety n'est pas la question ici. Tous les regards syntaxiquement et fonctionnellement bien et il devrait fonctionner pendant environ une demi-heure. Des ressources est une fuite mais la vraie question ici. L'application se bloque au bout d'environ une demi-heure parce que vous ne les fermez après utilisation. La base de données sera à son tour plus tôt ou plus tard près de la connexion elle-même pour qu'il puisse réclamer de nouveau.
Cela dit, vous n'avez pas à vous soucier de la mise en cache de PreparedStatements. Le pilote JDBC et DB se chargeront de cette tâche. Plutôt se soucier des fuites de ressources et rendre votre code JDBC aussi solide que possible. P>
public class ThreadedTask implements runnable { public run() { Connection connection = null; Statement statement = null; try { connection = DriverManager.getConnection(url); statement = connection.prepareStatement(sql); // ... } catch (SQLException e) { // Handle? } finally { if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {} if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {} } } }
Regardez Apache Commons dbUtils pour un emballage léger qui prend soin de tous les essayer / attraper.
Nous pouvons aussi utiliser JPA. Plus pratique ne peut pas l'être.
Si vous utilisez Java 7+: préfèrent utiliser « essayer avec des blocs de ressources ». Dans ce cas, vous ne pouvez pas oublier de fermer la connexion et la déclaration.
Ne pas stocker la connexion, la connexion Obtenez lorsque vous en avez besoin. Si vous avez besoin bettr performances utiliser un pool de connexion. AS Thilo dit ci-dessous ne partagent pas des choses entre les threads.