FAQ JDBCConsultez toutes les FAQ
Nombre d'auteurs : 8, nombre de questions : 162, dernière mise à jour : 3 juin 2015 Ajouter une question
Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums de http://www.developpez.com et de l'expérience personnelle des auteurs.
Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.
- Que sont les transactions ?
- Comment et quand annuler une transaction ?
- Que sont les niveaux d'isolation des transactions ?
- Comment faire des mises à jour groupées, ou Batch Updates ?
- Que renvoie l'exécution d'un batch ?
- Comment gérer les exceptions lors d'un batch ?
- Comment utiliser des points de sauvegarde dans les transactions ?
- Comment savoir si le driver supporte les transactions ?
Une transaction est un ensemble d'instructions devant s'exécuter d'un seul bloc. C'est-à-dire que les instructions sont soit toutes exécutées, soit toutes annulées. Si une seule instruction du bloc échoue, la transaction ne prend pas effet.
Par défaut, les Connection sont en mode auto-commit. C'est-à-dire que chaque instruction SQL est considérée comme une transaction. Vous pouvez changer ce comportement en utilisant la méthode setAutoCommit(boolean).
Dans le cas où l'auto-commit est désactivé, vous devrez appeler la méthode commit pour effectivement valider la transaction. Voici un exemple :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Connection connection = null; try{ connection = ...; connection.setAutoCommit(false); //traitement des différentes instructions composant la transaction connection.commit();// c'est ici que l'on valide la transaction connection.setAutoCommit(true); }catch(SQLException sqle){ //vous pourrez annuler ici la transaction en cas d'exception }finally{ try{connection.close();}catch(Exception e){} } |
Pour annuler une transaction, vous devez utiliser la méthode rollback. Cette méthode a pour effet d'annuler toutes les modifications faites par la transaction courante et de supprimer les verrous en place.
Voici un exemple :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Connection connection = null; try{ connection = ...; connection.setAutoCommit(false); //traitement des différentes instructions composant la transaction if(jeVeuxValider){ connection.commit();// c'est ici que l'on valide la transaction connection.setAutoCommit(true); }else{ connection.rollback(); } }catch(SQLException sqle){ try{connection.rollback();}catch(Exception e){} }catch(Exception e){ try{connection.rollback();}catch(Exception e){} }finally{ try{connection.close();}catch(Exception e){} } |
JDBC prévoit plusieurs niveaux d'isolation. Ces niveaux d'isolation déterminent la manière dont sont préservées les données durant la transaction. C'est-à-dire que JDBC est capable de verrouiller (en lecture ou écriture) les données tant que la transaction n'est pas validée.
Voici quatre des cinq niveaux d'isolation possibles, définis par des constantes de la classe Connection :
Niveau\Anomalie | Lecture impropre | Lecture non répétable | Lecture fantôme |
TRANSACTION_READ_UNCOMMITTED | possible | possible | possible |
TRANSACTION_READ_COMMITTED | impossible | possible | possible |
TRANSACTION_REPEATABLE_READ | impossible | impossible | possible |
TRANSACTION_SERIALIZABLE | impossible | impossible | impossible |
Le dernier niveau est TRANSACTION_NONE et indique que les transactions ne sont pas supportées.
Voici la définition des anomalies :
- Lecture impropre (dirty read) : cette anomalie se produit lorsqu'une transaction lit des données qui sont en train d'être modifiées par votre transaction (non encore validée) ;
- Lecture non répétable (non-repeatable read) : cette anomalie survient si une requête ne renvoie pas les mêmes résultats lors d'exécutions successives. C'est le cas si les données que vous lisez sont modifiées par une autre transaction (c'est un peu l'inverse de la lecture impropre) ;
- Lecture fantôme (phantom reads) : cette anomalie se produit si des exécutions successives d'une même requête renvoient des données en plus ou en moins. Cela peut être le cas si une autre transaction est en train de supprimer ou d'ajouter des données à la table.
Pour connaître le niveau d'isolation, vous pouvez utiliser la méthode getIsolationLevel de la classe Connection. De la même manière, vous pouvez changer ce niveau avec la méthode setIsolationLevel. Attention, toutes fois, car tous les SGBDR ne supportent pas tous les types d'isolation.
Depuis JDBC 2.0, la classe Statement (et ses dérivées) propose quelques méthodes pouvant faciliter les mises à jour groupées.
Voici un exemple :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | Connection connection = ... ; Statement statement = connection.createStatement(); if(connection.getMetaData().supportsBatchUpdates()){ connection.setAutoCommit(false); statement.clearBatch(); //on supprime les anciens batch statement.addBatch("INSERT ...."); statement.addBatch("UPDATE ..."); statement.addBatch("..."); int[] resultat = statement.executeBatch(); //voir les différents types de retours possibles connection.commit(); connection.setAutoCommit(false); } |
L'exécution d'un batch retourne un tableau d'entiers. Ceux-ci correspondent aux commandes insérées dans le batch et ont trois valeurs possibles.
- Statement.EXECUTE_FAILED : l'exécution de la commande a échoué, mais aucune exception n'a été levée.
- Statement.SUCCESS_NO_INFO : l'exécution a réussi, mais il n'y a aucune information disponible sur le nombre de lignes affectées par la mise à jour.
- Un entier supérieur ou égal à zéro : l'exécution a réussi. Cet entier représente le nombre de lignes affectées par la mise à jour.
La méthode executeBatch est susceptible de lever une BatchUpdateException si une des commandes lève une SQLException ou retourne un ResultSet. BatchUpdateException, étendant SQLException, offre les mêmes informations. On peut en plus obtenir un tableau d'entiers nous renseignant sur les résultats des commandes exécutées avant celle levant l'exception.
Voici un exemple de traitement :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Connection connection = ... ; Statement statement = ... ; try{ connection.setAutoCommit(false); // ajout des commandes au statement int[] resultats = statement.executeBatch(); if(lExecutionEstSatisfaisante){ connection.commit(); }else{ connection.rollback(); } }catch(BatchUpdateException bue){ int[] commandesExecutees = bue.getUpdateCounts(); System.out.println(commandesExecutees.length+ " commandes ont déjà été exécutées avant l'erreur "); connection.rollback(); }catch(SQLException sqle){ try{connection.rollback();}catch(Exception e){} }finally{ try{connection.setAutoCommit(true);}catch(Exception e){} try{statement.close();}catch(Exception e){} } |
La méthode rollback permet seulement d'annuler l'ensemble d'une transaction. Un mécanisme un peu plus intéressant a fait son apparition avec JDBC 3.0 : l'utilisation de points de sauvegarde tout au long de la transaction. Ces points de sauvegarde, représentés par l'interface Savepoint du package java.sql, permettent tout simplement de revenir en arrière dans la transaction, mais de manière ciblée.
Voici un exemple :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Connection connection = ... ; connection.setAutoCommit(false); //une première instruction Savepoint s1 = connection.setSavepoint("Premier point de sauvegarde"); //une deuxième instruction Savepoint s2 = connection.setSavepoint(); // point de sauvegarde anonyme //une troisième instruction Savepoint s3 = connection.setSavepoint("Troisième point de sauvegarde"); connection.releaseSavepoint(s2); // on enlève le second savepoint connection.rollback(s1); // toutes les modifications après s1 sont ignorées connection.commit(); // finalement seulement la première instruction est validée |
Pour savoir sir le driver supporte les transactions, vous pouvez utiliser les méthodes de DatabaseMetaData. Par exemple :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | DatabaseMetaData metadata = ...; if(metadata.supportsTransactions()){ System.out.println("Les transactions sont supportées"); if(metadata.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED){ //etc. } }else{ System.out.println("Ls transactions ne sont pas supportées"); } |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.