Etude exploratoire de Linq - CoDE - de l'Université libre de Bruxelles
Etude exploratoire de Linq - CoDE - de l'Université libre de Bruxelles
Etude exploratoire de Linq - CoDE - de l'Université libre de Bruxelles
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
sur <strong>de</strong>s données (typiquement <strong>de</strong>man<strong>de</strong> <strong>de</strong> lecture d’une donnée en cours <strong>de</strong> modification ou à<br />
modifier), les transactions (avec mécanismes <strong>de</strong> roll-back si satisfaire la transaction s’avère<br />
impossible) et la gestion <strong>de</strong>s exceptions Sql [12]. Dans ces trois domaines, la presque totalité <strong>de</strong>s<br />
problèmes pouvant survenir sont découverts à l’exécution, ce qui est toujours gênant lorsqu’on<br />
souhaite offrir un accès en ligne aux ressources. <strong>Linq</strong> manipule les objets entités en mémoire et donc<br />
crée un délai supplémentaire durant lequel <strong>de</strong>s accès concurrentiels peuvent apparaître. Un objet<br />
entité contient plusieurs indicateurs permettant <strong>de</strong> savoir s’il correspond ou non à son homologue en<br />
base <strong>de</strong> données et le DataContext peut donc détecter lorsqu’un conflit survient. Il est possible<br />
d’assigner une politique <strong>de</strong> gestion <strong>de</strong> conflits plus ou moins fine selon ce qui est désiré. Nous<br />
n’allons pas trop nous étendre là-<strong>de</strong>ssus, les heuristiques <strong>de</strong> résolution <strong>de</strong> tels conflits dépassent<br />
largement le cadre <strong>de</strong> ce travail. Nous nous contenterons <strong>de</strong> dire que les opérations concourantes<br />
ont été envisagées et que le DataContext est en mesure <strong>de</strong> réaliser une gestion <strong>de</strong> conflits assez<br />
performantes pour peu qu’une politique adaptée lui soit fournie. Les informations <strong>de</strong><br />
synchronisations jouent également un rôle important à ce niveau. En effet, lorsque le comportement<br />
est laissé par défaut (il s’agit du IsDbGenerated), le DataContext ira régulièrement s’informer auprès<br />
<strong>de</strong> la base <strong>de</strong> données pour s’enquérir d’éventuels changements survenus pour chaque attribut<br />
ayant ce comportement. Le comportement inverse est également possible. Lorsqu’une entité doit<br />
modifier l’une <strong>de</strong> ses propriétés, elle en avertit le DataContext et celui-ci va marquer l’entité avec le<br />
statut « modifié » le temps <strong>de</strong> répercuter les changements dans la base <strong>de</strong> données. Cela nous laisse<br />
déjà entrevoir les possibilités <strong>de</strong> conflits engendrés par <strong>de</strong>s opérations concourantes. Microsoft, par<br />
le biais <strong>de</strong> la bibliothèque en ligne MSDN [4], propose plusieurs politiques <strong>de</strong> gestion <strong>de</strong> conflits mais,<br />
comme dit plus haut, tout cela dépasse le cadre <strong>de</strong> notre étu<strong>de</strong>.<br />
Les transactions sont utilisées systématiquement par les objets <strong>de</strong> type DataContext. Cela n’a rien<br />
d’étrange quand nous avons vu que le DataContext est l’unique lien entre la base <strong>de</strong> données et<br />
l’ensemble <strong>de</strong>s entités qui lui sont associées. Lorsque le DataContext se voit soumettre une ou<br />
plusieurs requêtes, il effectue en priorité les changements sur les entités en mémoire et va, selon la<br />
disponibilité <strong>de</strong> la connexion à la base <strong>de</strong> données, soumettre à son tour les changements à la base<br />
<strong>de</strong> données. Chaque requête soumise au DataContext est encapsulée dans une transaction au sens<br />
relationnel du terme. Il est néanmoins possible pour le programmeur d’élargir une transaction, en y<br />
ajoutant <strong>de</strong>s modifications. La classe TransactionScope (disponible dans la bibliothèque<br />
System.Transactions) permet cette opération le plus naturellement qui soit [4]. Il suffit d’instancier<br />
un nouvel objet TransactionScope sans paramètre et d’y inclure l’ensemble <strong>de</strong>s opérations<br />
souhaitées, comme le montre le morceau <strong>de</strong> co<strong>de</strong> suivant :<br />
using (TransactionScope ts = new TransactionScope())<br />
{<br />
monDataContext.SubmitChanges();<br />
//Soumission <strong>de</strong> l'ensemble <strong>de</strong>s requêtes en attente<br />
}<br />
//... co<strong>de</strong> supplémentaire éventuel<br />
ts.Complete();<br />
Nous avons encore à abor<strong>de</strong>r le problème <strong>de</strong>s exceptions. Les auteurs <strong>de</strong> « Programming <strong>Linq</strong> » [1]<br />
nous présentent trois sources principales d’exceptions, la création d’un DataContext, les accès à une<br />
base données en lecture et ceux en écriture. Notons que <strong>Linq</strong> ne possè<strong>de</strong> pas d’exceptions qui lui