Mise en évidence du comportement des évènements de table d'Access 2010 en environnement multi-utilisateurs

Office 2010

Ce court article met en évidence le comportement des évènements de table au sein d'un environnement multi-utilisateurs. Il est destiné à un public averti maîtrisant les concepts d'évènements de table.

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Dans un précédent document, je vous proposais de comprendre le fonctionnement des évènements de table au sein d'une transaction de données. Cette fois-ci, je vous propose de nous intéresser à leur comportement dans un environnement multi-utilisateurs et plus précisément de déterminer comment se traduisent, dans l'application d'utilisateur B, les modifications apportées par un utilisateur A.

II. Mise en situation

Soit une table tblClient possédant la structure suivante :

  • ID (Clé primaire)
  • Nom
  • Prénom
  • Matricule

Le matricule d'un client est composé des deux premières lettres de son nom, suivies des 2 premières de son prénom. Un indice vient compléter la donnée pour éviter les doublons :

ID Nom Prenom Matricule
1 NORD Paul NOPa1
2 NORD Pauline NOPa2


Celui-ci est généré par la DataMacro suivante placée dans l'évènement AfterInsert() de la table tblClient

 
Sélectionnez
Look Up A Record In qryMatricule
  Where  qryMatricule.N=left(TblClient.Nom,2) AND qryMatricule.P=left(tblClient.Prenom,2)
  Alias rec_Matricule

  SetLocalVar(vMatricule,[NB])

Edit Record
  Set Field(Matricule,Left(Nom,2) & left(Prenom,2) & VMatricule
End Edit Record


Code de la requête qryMatricule :

 
Sélectionnez
SELECT COUNT(ID) AS NB, Left(Nom,2) AS N, Left(Prenom,3) AS P
FROM TBLCLIENT
GROUP BY Left(Nom,2), Left(Prenom,3);


L'étude du contenu de la table tblClient montre bien que le calcul est élaboré après l'insertion de l'enregistrement. En effet, si ce n'était pas le cas, le matricule de Paul Nord se terminerait par 0 (Count(ID) d'une table vide est égal à 0). On en conclut donc, que pour l'utilisateur ayant opéré la saisie, l'évènement AfterInsert intervient (comme son nom l'indique) après la création de la nouvelle ligne par le moteur de base de données. Mais qu'en est-il pour les autres utilisateurs ? Ont-ils la même vision de la table tblClient ? C'est justement à cette question que le prochain chapitre va tenter de répondre.

III. Banc d'essai

Il existe deux hypothèses possibles concernant le contenu que voit l'utilisateur B lorsque la saisie de A est traitée par l'évènement AfterInsert :

  • Soit B voit l'enregistrement en cours de création, mais avec le champ Matricule non renseigné (car non calculé), auquel cas nous pourrions parler d'état incohérent de la base.
  • Soit B ne voit pas ce nouvel enregistrement qui ne lui sera disponible qu'une fois tous les évènements de table terminés.

Pour mettre en évidence ces hypothèses, nous allons modifier la DataMacro de telle sorte qu'elle nous laisse le temps de rafraîchir l'affichage du contenu de la base de l'utilisateur B. La solution la plus simple et la plus efficace consiste à créer une fonction VBA nommée Attendre dans un module et de la lancer via la méthode SetLocalVar.

Fonction Attendre :

 
Sélectionnez
Function Attendre()
While True
  DoEvents
Wend
End Function


DataMacro AfterInsert :

 
Sélectionnez
SetLocalVar(vTemp;Attendre())
Look Up A Record In qryMatricule
  Where  qryMatricule.N=left(TblClient.Nom,2) AND qryMatricule.P=left(tblClient.Prenom,2)
  Alias rec_Matricule

  SetLocalVar(vMatricule,[NB])

Edit Record
  Set Field(Matricule,Left(Nom,2) & left(Prenom,2) & VMatricule
End Edit Record


L'utilisateur A travaille sur la base de données dorsale tandis que B est connecté à celle-ci via le mécanisme de table liée.

Avant le test, nous pouvons constater que A et B disposent du même contenu de la table tblClient :

ID Nom Prenom Matricule
1 NORD Paul NOPa1
2 NORD Pauline NOPa2


Tentons une insertion d'un nouveau client depuis l'application de l'utilisateur A.

ID Nom Prenom Matricule
1 NORD Paul NOPa1
2 NORD Pauline NOPa2
3 NORD Polux  


Comme convenu, l'application Access de A ne rend pas la main puisque occupée par la boucle infinie de la fonction Attendre(). On en déduit au passage que les évènements de table ne sont pas asynchrones avec Access. Il est nécessaire de terminer toutes les macros pour être autorisé à poursuivre. A ce stade, voici l'état de la table clients de l'utilisateur B après rafraîchissement :

ID Nom Prenom Matricule
1 NORD Paul NOPa1
2 NORD Pauline NOPa2


L'enregistrement actuellement affecté par l'évènement AfterInsert n'est pas visible.

Un rapide retour dans l'éditeur VB de A permet de stopper la fonction en remplaçant la constante True par False. Instantanément, le champ Matricule est mis à jour et affiché sur l'écran de A :

ID Nom Prenom Matricule
1 NORD Paul NOPa1
2 NORD Pauline NOPa2
3 NORD Polux NOPo1


Simultanément, un rafraîchissement de la table de l'utilisateur B montre les mêmes données.

ID Nom Prenom Matricule
1 NORD Paul NOPa1
2 NORD Pauline NOPa2
3 NORD Polux NOPo1

IV. Conclusion

Ce rapide test permet de nous assurer qu'à aucun moment la base n'apparaît dans un état incohérent à un quelconque utilisateur. L'exemple est ici borné à l'évènement AfterInsert mais il faut savoir qu'il en va de même pour les autres évènements After*.

Si cette conclusion n'exprime pas grand-chose pour vous, il faut en fait penser à l'ensemble des situations où les évènements de table peuvent être utilisés et y voir les avantages et les inconvénients. Dans le cas ci-dessus, B est ravi d'apprendre qu'il ne listera pas des clients non finalisés, en revanche, s'il lance la création de NORD Polette alors que A est ralenti pour X raisons dans son évènement de table, il est fort probable qu'ils s'allouent tous les deux le même matricule pour, hélas, deux clients différents. Il est donc primordial que les DataMacros soient optimisées au maximum de telle sorte à minimiser ces risques.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2009 Christophe Warin. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.