2010-05-08 6 views
3

Est-ce que ResultSet est sûr? Ma question se pose parce que dans mon programme j'ai utilisé une instruction différente pour chaque requête j'ai déclaré un ResultSet comme une variable locale mais cela me donne une erreur d'opération non autorisée après que ResultSet soit fermé. Mais mes instructions fonctionnent comme j'utilise les instructions dans la requête d'insertion et de suppression. J'ai commenté la partie ResultSet et n'ai pas eu l'erreur !!IS ResultSet thread safe

Répondre

5

Le vrai problème est que vous partagez des objets Statement entre plusieurs threads. Chaque fois que vous "exécutez" une instruction, le ResultSet renvoyé précédemment est automatiquement fermé. Dans ce cas, les objets ResultSet "appartiennent" à un thread différent qui n'a pas encore fini de l'utiliser. D'où l'exception ...

Vous ne devez pas partager des objets Connection, Statement/PreparedStatement ou ResultSet entre plusieurs threads. Chaque thread devrait acquérir et libérer ses propres ressources.

+1

mais ne ferait pas une connexion pour chaque thead conduit à beaucoup de connexion et la fermeture evrytime conduire à des frais généraux –

+0

Pas si vous utilisez un pool de connexion.En outre, une solution inefficace est meilleure qu'une «solution» qui se brise en raison de bogues de concurrence. –

+0

Comment évaluez-vous proxool pour le regroupement de connexions? est-il un meilleur outil qui peut être utilisé? –

3

Non, ResultSet ne doit pas être exposé à plus d'un thread. Un ResultSet ne doit jamais avoir une étendue supérieure à une méthode unique: exécutez la requête, mappez le ResultSet dans un objet ou une collection et fermez le ResultSet dans la même étendue que celle dans laquelle il a été créé.

La manière correcte de fermer un ResultSet est dans un bloc finally dans son propre try/catch.

J'ai regardé le code dans votre autre question. Il a besoin d'un refactoring sérieux et complet. Ce n'est pas surprenant que vous ayez des problèmes avec ça. Voici quelques suggestions:

  1. Suivez les conventions de codage Sun Java. Cela peut sembler trivial, mais tout ce qui rend votre code plus difficile à lire est une mauvaise idée. Vos classes "doComms" et "savetodatabase" cassent la convention "noms de classes commencent par une majuscule".
  2. Le nommage est important. "doComms" n'est pas mon idée d'une bonne abstraction.
  3. Les nombres/constantes magiques sont partout. Ils rendront votre code plus difficile à changer plus tard.
  4. Java est un langage orienté objet; vous écrivez dans un autre style tout à fait. Quand je vois "insert studentinfo", je me demande où est la classe Student.
  5. Votre code JDBC ne gère pas les ressources correctement. Juste curieux - vous essayez d'apprendre à écrire un serveur?

Y a-t-il une raison pour laquelle vous n'utilisez pas un moteur de servlet comme base pour cette application? Les sockets sont un endroit de très bas niveau pour commencer à résoudre un problème comme celui-ci.

+0

oui j'essaye d'écrire un serveur ... merci pour la réponse. –

+0

@ user335990 - mais ** pourquoi ** essayez-vous de le faire? –

2

Les quelques fois où j'ai écrit JDBC codé à la main, ça a été à la fois moche et sujet aux erreurs. Bien sûr, cela pourrait être juste moi, mais vous pouvez avoir de meilleurs résultats avec l'utilisation des classes Spring JDBC data access. Vous n'avez pas besoin d'utiliser tout le conteneur de ressorts, juste une DataSource et une classe JdbcTemplate d'un ressort.

Il applique un modèle d'utilisation à JDBC à la fois thread-safe et sans risque pour les ressources.

+0

D'accord avec ça. Vous réinventez la roue, mal. Je suis tout à fait pour enseigner aux gens comment ne pas se tirer une balle dans le pied, mais je ne peux en faire autant en même temps. – bwawok