Transactions
Vous utilisez les transactions quand vous avez à faire une série dopérations
individuelles mais dépendantes les unes des autres, en ayant la possibilité, une
fois que toutes les commandes ont été exécutées, daccepter ou dannuler dun
bloc toutes les opérations effectuées.
Lexemple le plus classique est le transfert dun compte à un autre à la banque. Si
quelque chose survenait entre le moment où vous retirez largent du premier
compte et le moment où il est déposé dans lautre, largent se retrouverait « dans
les limbes ». Ça prend un mécanisme qui permet de faire les deux opérations
comme sil ne sagissait que dune seule, et de pouvoir lannuler en un bloc si un
problème est détecté.
Une transaction servant habituellement à assurer une cohérence entre plusieurs
opérations différentes sur plusieurs tables différentes, elle doit sappliquer sur une
connexion. Comme dans .NET on travaille en mode déconnecté, le mécanisme
peut sappliquer à plusieurs niveaux.
Lignes individuelles
Au niveau des lignes individuelles, une série de méthodes BeginEdit / EndEdit /
CancelEdit correspond aux plus familiers BeginTran / Commit / RollBack. Elles
peuvent être utilisées pour développer un petit mécanisme de transactions très
localisé.
Quand vous chargez une table dans un DataSet, chaque DataRow contient une
ligne quon dit Original.
Dim ds As Dataset
Dim row As DataRow
Dim tb As DataTable
DataAdapterQuelconque.Fill(ds)
tb = DataSet.Tables("Clients")
row = tb.Rows(2)
Debug.Write (row.ToString) 'Donne par exemple "Québec"
Quand vous modifiez la ligne, lOriginal est conservé, et une copie appelée
Current est créée. Toutes les opérations sur la DataRow se font sur cette copie.
row.Item("Ville")= "Montréal"
ou row("Ville")= "Montréal"
Si vous appelez la méthode BeginEdit sur la ligne, une troisième copie appelée
Proposed est créée, et à partir de ce moment, les opérations se font sur la
Proposed plutôt que sur la Current.
row.BeginEdit()
row.Item("Ville")= "Laval"
Pour accéder aux données « cachées », vous pouvez utiliser un overload de la
propriété Item :
row.Item("Ville",DataRowVersion.Original) -> Québec
row.Item("Ville",DataRowVersion.Current) -> Montréal
row.Item("Ville",DataRowVersion.Proposed) -> Laval
Si vous faites un CancelEdit à ce moment, vous éliminez simplement la valeur
Proposed :
row.CancelEdit()
row.Item("Ville",DataRowVersion.Original) -> Québec
row.Item("Ville",DataRowVersion.Current) -> Montréal
row.Item("Ville",DataRowVersion.Proposed) -> Nothing
Par contre, si vous faites un EndEdit, les changements apportés sont enregistrés,
la valeur Proposed devient la Current. La ligne originale reste toujours
disponible :
row.EndEdit()
row.Item("Ville",DataRowVersion.Original) -> Québec
row.Item("Ville",DataRowVersion.Current) -> Laval
row.Item("Ville",DataRowVersion.Proposed) -> Nothing
Notez que bien que notre démonstration soit sur un seul champ, le mécanisme
joue sur lensemble des champs de la ligne.
Dans la table
Gérer les transactions ligne par ligne peut devenir fastidieux, alors la table
possède deux méthodes qui permettent de faire le travail dun coup sur toutes les
lignes actuellement en cours dédition.
RejectChanges appelle CancelEdit sur toutes les lignes de la table, et en plus,
assume que tous les changements faits depuis le début des opérations sur la table
sont rejetés. Vous vous retrouvez en fait avec le DataSet tel quil était juste au
moment de le créer en appelant un Fill sur un DataAdapter :
tb.RejectChanges()
row.Item("Ville",DataRowVersion.Original) -> Québec
row.Item("Ville",DataRowVersion.Current) -> Québec
row.Item("Ville",DataRowVersion.Proposed) -> Nothing
AcceptChanges appelle EndEdit sur toutes les lignes de la table et en plus,
assume que tous les changements apportés deviennent final.
tb.AcceptChanges()
row.Item("Ville",DataRowVersion.Original) -> Laval
row.Item("Ville",DataRowVersion.Current) -> Laval
row.Item("Ville",DataRowVersion.Proposed) -> Nothing
row.RowState() -> Unchanged
Important Toutes les lignes ajoutées ou modifiées deviennent permanentes et les lignes
détruites le sont vraiment. Si vous déclenchez un Update, sur-le-champ, il ne se
passera rien. Et si vous déclenchez un Update plus tard, il risque dy avoir des
conflits parce que les enregistrements « originaux » du DataSet ne
correspondront plus à ceux de la base de données.
AcceptChanges nest donc habituellement appelé quaprès avoir fait un Update.
Dans le DataSet
Le DataSet possède aussi des méthodes AcceptChanges et RejectChanges, qui
appellent les méthodes correspondantes sur toutes les tables faisant partie du
DataSet.
Objet Transaction sur la Connection
Pour des transactions plus globales et plus traditionnelles, qui jouent au moment
décrire les données dans la base de données plutôt que dans le DataSet en
mémoire, vous devez utiliser un objet Transaction.
Notez que le mécanisme est très variable dépendant de la base de données.
Certaines sont pessimistes et vont accumuler les transactions en mémoire en
attendant davoir le OK avant de les écrire dans la BD. Dautres sont plus
optimistes et assument quil est rare dannuler une transaction. Elles vont donc
écrire les changements dans la BD, en disposant dun mécanisme permettant de
revenir en arrière advenant une annulation.
Tout ça est relativement transparent pour le programmeur ADO.NET. La
technique est la même dans tous les cas. Cest le fournisseur ADO qui soccupe
des détails.1
Mais pour concevoir des transactions efficaces, vous devez bien connaître le
mécanisme de transactions dans la base de données que vous utilisez.
1 Si vous avez besoin dun contrôle très serré des transactions, vous devrez vous référer
à la documentation de votre fournisseur de base de données.
Vous créez tout dabord une transaction en appelant la méthode BeginTransaction
de la Connection que vous allez utiliser. La Connection doit être préalablement
ouverte.
Dim cn As New OleDbConnection(pcConnectionString)
Dim tr As OleDbTransaction
cn.Open()
tr = cn.BeginTransaction()
Vous assignez ensuite la transaction à la propriété Transaction dun objet
Command. La transaction sappliquera à toutes les opérations effectuées sur cet
objet. Dim cmd1 as New OleDBCommand("INSERT ", cn, tr)
Dim cmd2 as New OleDBCommand("DELETE ", cn)
cmd2.Transaction = tr
Comme vous pouvez le constater, la même transaction peut être appliquée à
plusieurs commandes. Ainsi, pour avoir une transaction lors dun Update dun
DataSet, il faut avoir associé chacune des commandes du DataAdapter
(InsertCommand, DeleteCommand et UpdateCommand) avec la même
transaction.
Toutes les opérations subséquentes sur ces objets Command font partie de la
transactiont :
cmd1.ExecuteNonQuery
cmd2.ExecuteNonQuery
Vous terminez avec un Commit sur lobjet Transaction dans le cas où toutes les
opérations se sont déroulées selon les prévisions, ou avec un RollBack dans le cas
où un problème a été détecté.
If OK Then
tr.Commit()
Else
tr.Rollback()
End If
Si vous avez une commande qui crée 12 enregistrements et une autre qui efface
35 enregistrements et quune erreur survient au sixième DELETE un
enregistrement verrouillé par un autre utilisateur par exemple un Rollback
annule tout, incluant lajout des 12 et la suppression des 5 premiers
enregistrements.
Les transactions imbriquées sont possibles.
La compréhension complète des mécanismes de transaction est un cours en soi, et
relève plus de la gestion des bases de données que de la programmation comme
telle2. Nous ninsisterons pas beaucoup plus, sauf pour dire aux initiés quil est
possible de déterminer le niveau disolation3 soit en créant la transaction.
tr = cn.BeginTransaction(IsolationLevel.Serializable)
Si vous travaillez avec SQL Server, notez que lobjet SqlTransaction permet
beaucoup plus de choses que le OleDbTransaction. Si vous êtes familier avec les
notions de transactions nommées et de SavePoints en Transact-SQL par exemple,
et que vous voulez utiliser ce mécanisme dans votre code .NET, vous devrez
absolument passer par des objets Sql, les objets OleDb noffrant pas cette
possibilité.
Transact-SQL permet par ailleurs de contrôler les transactions directement dans
vos commandes SQL si vous le désirez. Utiliser ces commandes dans vos
procédures stockées pourrait être intéressant si vous devez absolument utiliser des
objets OleDb (vous supportez peut-être un BD en plusieurs formats) et que vous
voulez obtenir un niveau de contrôle plus avancé dans vos transactions sur SQL
Server.
Transactions distribuées
Une transaction distribuée en est une qui travaille sur des opérations effectuées
sur plusieurs ressources, par exemple, quand vous travaillez simultanément avec
deux bases de données, en implémentant un mécanisme de réplication entre une
base de données maître et une base de données locale.
Vous pourriez aussi vouloir établir une entre plusieurs classes et/ou dll roulant
peut-être sur des ordinateurs différents.
Cest un mécanisme qui sapplique aux membres des classes impliquées plutôt à
des bases de données, mais si les classes développées de cette façon créent des
connexions ADO, la transaction implémentée sur la classe contrôle indirectement
les transactions sur ces (un Rollback sur la classe va sappliquer à la Connection).
Elles ne sont supportées que dans des environnements très avancés (oubliez ça
avec Access) et impliquent généralement lintervention du système dopération.
Les versions modernes de Windows supportent les transactions distribuées au
travers des Component Services, une composante de COM+.
2 Une excellente référence pour tout ce qui a trait à SLQ Server, le livre de Karen
Delaney, dont vous trouverez les coordonnées dans la bibliographie, à la fin du manuel.
3 Le niveau disolation gère comment les locks (verrouillage) vont se faire pendant la
transaction. Par exemple, un niveau Serializable comme celui de notre ligne de code
implique que tous les enregistrements du DataSet sont verrouillées pour les autres
utilisateurs le temps que dure la transaction. Il faut que la base de données supporte ce
mécanisme.
1 / 6 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !