web-dev-qa-db-fra.com

Java 7 Gestion automatique de ressources JDBC (Essayez-la-Ressources)

Comment intégrer l'idiome JDBC commun de créer/recevoir une connexion, interrogeant la base de données et éventuellement traiter les résultats avec Java Condition automatique des ressources, la déclaration Type-with-Resources? ( Tutoriel )

Avant Java 7, le modèle habituel était quelque chose comme ceci:

Connection con = null;
PreparedStatement prep = null;

try{
    con = getConnection();
    prep = prep.prepareStatement("Update ...");
    ...
    con.commit();
}
catch (SQLException e){
    con.rollback(); 
    throw e;
}
finally{
    if (prep != null)
        prep.close();
    if (con != null)
        con.close();
}

Avec Java 7 Vous pouvez aller pour:

try(Connection con = getConnection(); PreparedStatement prep = con.prepareConnection("Update ..."){

   ...
   con.commit();
}

Cela fermera le Connection et le PreparedStatement, mais qu'en est-il de la restauration? Je ne peux pas ajouter de clause de capture contenant la restauration, car la connexion n'est disponible que dans le bloc d'essai.

Définissez-vous toujours la connexion en dehors du bloc d'essai? Quelle est la meilleure pratique ici, surtout si la mise en commun de la connexion est utilisée?

37
TPete
try(Connection con = getConnection()) {
   try (PreparedStatement prep = con.prepareConnection("Update ...")) {
       //prep.doSomething();
       //...
       //etc
       con.commit();
   } catch (SQLException e) {
       //any other actions necessary on failure
       con.rollback();
       //consider a re-throw, throwing a wrapping exception, etc
   }
}

Selon la Oracle Documentation , vous pouvez combiner un bloc d'essai avec des ressources avec un bloc d'essai régulier. IMO, l'exemple ci-dessus capture la bonne logique, qui est:

  • Tenter de fermer la systémation préparée si rien ne va pas
  • Si quelque chose ne va pas dans le bloc intérieur, (peu importe ce qui est, c'est) faire rouler la transaction en cours
  • Tenter de fermer la connexion, peu importe quoi
  • Si quelque chose ne va pas en train de fermer la connexion, vous ne pouvez pas retourner la transaction (comme c'est une méthode sur la connexion, qui est maintenant en état indéterminé), alors n'essayez pas

IN Java 6 et plus tôt, je le ferais avec un ensemble imbriqué abrutif d'essais d'essais (Essayez-trayon extérieur-enfin, try-trayon moyen, TRY-TRY-TRAIT-enfin). ARM Syntaxe fait ce erser.

40
Sean Reilly

IMO, déclarant que la connexion et la constitution préparées extérieures à l'extérieur sont la meilleure façon disponible dans ce cas.

4
Garbage

Si vous souhaitez utiliser une connexion groupée en transaction, vous devez l'utiliser de cette manière:

try (Connection conn = source.getConnection()) {
        conn.setAutoCommit(false);
        SQLException savedException = null;
        try {
            // Do things with connection in transaction here...
            conn.commit();
        } catch (SQLException ex) {
            savedException = ex;
            conn.rollback();
        } finally {
            conn.setAutoCommit(true);
            if(savedException != null) {
                throw savedException;
            }
        }
    } catch (SQLException ex1) {
        throw new DataManagerException(ex1);
    }

Cet exemple de code traite les valeurs de l'autocommande.

Remarque, que l'utilisation savedException _ enregistre une exception au cas où conn.rollback() jette un autre. De cette façon, le blocage finalement lancera une exception "droite".

2
user3698328