IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Tutoriel JDBC
10.0 Utilisation des Transactions

Parfois, vous ne voulez pas qu'une instruction prenne effet sans qu'une autre lui succède. Par exemple, quand le propriétaire du The Coffee Break met à jour le montant de café vendu chaque semaine, il aimerait aussi mettre à jour le montant total des ventes jusqu'à maintenant. Donc, il ne veut pas mettre à jour l'un sans mettre à jour l'autre, sinon les données ne seraient pas crédibles. La manière pour être sûr que toutes les actions et interactions voulues s'effectuent est d'utiliser une transaction. Une transaction est un jeu de une ou plusieurs instructions qui sont exécutées ensembles de façon unitaire, donc toutes les instructions sont exécutées, ou aucune.

10.1 Désactiver le mode Auto-commit

Quand une connexion est crée, elle est en mode auto-commit. Ce qui veut dire que chaque instruction SQL est traitée comme une transaction et prendra automatiquement effet après sa bonne exécution. (Pour être plus précis, une instruction SQL prend automatiquement effet sur la base de données lorsqu'elle est terminée, et non pas quand elle est exécutée. Une instruction est terminée quand tous ses résultats et toutes ses mises à jour ont été rapportées. Dans la plupart des cas, une instruction est terminée, puis les changements prennent effets sur la base de données, puis elle est exécutée).

La manière d'autoriser deux ou plusieurs instructions à être groupées dans une transaction est de mettre hors service le mode auto-commit. C'est ce que nous faisons à la ligne suivante, où conn est notre connexion active :

conn.setAutoCommit(false);

10.2 Pour que la transaction prenne effet sur la BD

Une fois que le mode auto-commit est désactivé, aucune instruction SQL ne prendra effet jusqu'à ce que la méthode commit soit employée. Toutes les instructions exécutées après l'appel de la méthode commit seront inclues dans la transaction et donc, pourront prendre effet en tant qu'unité. Le code qui suit, où conn est la connexion active, illustre la transaction :

conn.setAutoCommit(false);
PreparedStatement updateVentes = conn.preparedStatement(
"UPDATE CAFE SET VENTE = ? WHERE NOM_CAFE LIKE ?");
updateVentes.setInt(1,50);
updateVentes.setString(2, "Colombian");
updateVentes.executeUpdate();
PreparedStatement updateTotal = conn.preparedStatement(
"UPDATE CAFE SET TOTAL = TOTAL + ? WHERE" +
"NOM_CAFE LIKE ?");
updateTotal.setInt(1,50);
updateTotal.setString(2,"Colombian");
updateTotal.executeUpdate();
conn.commit();
conn.setAutoCommit(true);



Dans cet exemple, le mode auto-commit est désactivé pour la connexion conn, ce qui veut dire que les deux prepared statements updateVentes et updateTotal prendront effet dans la base de données quand la méthode commit est appelée. Quand la méthode commit est appelée (automatiquement quand auto-commit est activée ou explicitement quand il est désactivé), tous les changements résultants des instructions de la transaction seront permanent. Dans ce cas, cela signifie que les colonnes VENTES et TOTAL pour le café Colombian ont été modifiées à 50 (Si TOTAL était 0) et retiendra cette valeur jusqu'à ce qu'elle soit modifié par une instruction.

La dernière ligne de l'exemple précédent active le mode auto-comit, ce qui veut dire que chaques instructions prendront dès lors effet automatiquement sur la base de données quand elle sera terminée. Vous reviendrez donc à l'état par défaut, celui où vous n'avez plus à appeler la méthode commit. Il est conseillé de désactiver le mode auto-commit uniquement quand vous être en mode transaction. De cette façon, vous réduisez les chances de conflit au niveau des entrées dans la base de données avec les autres utilisateurs.

10.3 Utiliser les transactions pour préserver l'intégrité des données

En plus de grouper les instructions ensembles pour être exécutées unitairement, les transactions peuvent aider à préserver l'intégrité de données dans une table. Par exemple, imaginons qu'un employé était supposé entrer les nouveaux prix du café dans la table CAFE, mais ne l'a pas fait depuis quelques jours. Pendant ce temps, les prix ont augmentés, et le propriétaire décide de mettre à jour les nouveaux prix dans la table. L'employé se décide finalement à entrer les prix n'étant plus à jour dans la base de données en même temps que le propriétaire met à jour la table. Après avoir insérer les prix non à jour, l'employé réalise qu'ils ne sont plus valides, et donc appel la méthode rollback de l'objet Connexion afin d'annuler les effets de ses manipulations. (La méthode rollback met fin à une transaction et restaure les valeurs présentes avant qu'elles aient été mises à jour) Mais en même temps, le propriétaire exécute une instruction SELECT puis affiche les nouveaux prix. Dans cette situation, il est possible que les prix affichés par le propriétaire proviennent d'un rollback contenant les anciens prix, rendant l'affichage des prix incorrects.

Ce genre de situation peut être évitée en utilisant les transactions. Si un SGBD supporte les transactions, et la plupart le font, il fournira certains niveaux de protection contre les conflits qui peuvent survenir quand on accède à des données au même moment.

Pour éviter les conflits durant une transaction, un SGBD utilise des verrous, mécanisme bloquant l'accès aux données utilisées par la transaction aux autres utilisateurs. Une fois qu'un verrou est posé, il restera en place jusqu'à ce qu'une transaction soit envoyée vers la base de données pour qu'elle puisse y prendre effet, ou vers un rollback. Par exemple, un SGBD pourra verrouiller la ligne d'une table jusqu'à ce que les mises à jour aient été validées. L'effet de ce verrou peut être de prévenir un utilisateur contre les valeurs erronées.

La manière dont les verrous sont posés détermine le niveau d'isolation de la transaction, pouvant aller jusqu'à bloquer totalement les transactions.

Un exemple de niveau d'isolation de transaction est TRANSACTION_READ_COMMITTED qui n'autorise l'accès à aucune valeur jusqu'à ce qu'elles aient été validées dans la base de données. En d'autre terme, si le niveau d'isolation de la transaction est TRANSACTION_READ_COMMITED, le SGBD ne permettra donc pas de pouvoir lire des valeurs erronées. L'interface Connexion inclue cinq niveaux d'isolation que vous pourrez utiliser avec JDBC.

Normalement vous n'avez pas besoin de faire quoi que ce soit en ce qui concerne le niveau d'isolation de transaction, vous pouvez toujours utiliser celui par défaut de votre SGBD. JDBC vous permet de savoir quel niveau d'isolation votre SGBD utilise (par le biais de la méthode getTransactionIsolation) et vous permet aussi de définir un autre niveau que celui utilisé (grâce à setTransactionIsolation). Gardez à l'esprit que même si JDBC vous permet de définir un niveau de transaction, il faut quand même que les drivers utilisés et le SGBD utilisé le supporte.

10.4 Quand appeler la méthode RollBack

Comme mentionné plus tôt, appeler la méthode rollback annule une transaction et remet les valeurs qui ont été modifiées à leurs valeurs originales. Si vous essayez d'exécuter une ou plusieurs instructions dans une transaction et que vous avez une SQLExeption, vous devrez utilisez la méthode rollback pour annuler la transaction et la recommencer depuis le début. C'est la seule façon d'être sûr de ce qui a été pris en compte sur la base de données, et ce qui ne l'a pas été. Une SQLException vous indique que quelque chose ne fonctionne pas, mais elle ne vous indique pas ce qui à été pris en compte ou pas. Donc vous ne pouvez pas compter sur le fait que rien n'a été mis à jour sur la BD, appeler la méthode rollback est la seule façon d'être sûr.

 

Précédent Suivant