4.10. Gestion de comptes bancaires
On considère un système de gestion de comptes
bancaires permettant d'effectuer les deux opérations suivantes
:
CredDeb_Compte (Numéro_Compte,
opération, somme) crédite ou débite le compte
Numéro_Compte de la valeur
somme en fonction de l'opération
demandée (opération =
débiter ou
créditer).
Donner_Solde (Numéro_Compte,
var Solde) renvoie le Solde du
compte.
Un client peut accéder à chacune de ces
opérations indépendamment les unes des autres et plusieurs clients
accèdent en parallèle au système de gestion des comptes
bancaires. On supposera que chaque compte bancaire est stocké sur disque
dans un fichier appelé
Fichier_Compte.
On donne ci-dessous le pseudo-code de ces deux fonctions
:
procédure CredDeb_Compte (Numéro_Compte, opération, somme)
début --lecture dans le fichier Fichier_Compte
-- du solde du compte Numéro_Compte
Lire (Fichier_Compte, Numéro_Compte, solde_compte);
si (opération = débiter)
alors solde_compte := solde_compte - somme;
sinonsolde_compte := solde_compte + somme;
fsi
-- écriture dans le fichier Fichier_Compte
-- du nouveau solde du compte Numero_Compte
Ecrire (Fichier_Compte, Numéro_Compte, solde_compte);
fin
procédure Donner_Solde (Numéro_Compte, var Solde)
début -- lecture dans le fichier Fichier_Compte
-- du solde du compte Numéro_Compte
Lire (Fichier_Compte, Numéro_Compte, solde_compte);
Solde := solde_compte;
fin
A- En
prenant un exemple, montrez que des incohérences peuvent survenir sur le
solde d'un compte si plusieurs utilisateurs accèdent à un compte
en parallèle.
B- On dispose des deux opérations suivantes
:
Verrouiller (Nom_Fich)
qui bloque le processus effectuant cette opération si un autre processus
a verrouillé le fichier
Nom_Fich
Déverrouiller
(Nom_Fich) qui libère l'accès au fichier
Nom_Fich et réveille un processus
bloqué par l'opération Verrouiller
(Nom_Fich), si il en existe un.
Comment utilisez ces opérations pour résoudre le
problème de la question A. Justifiez votre raisonnement.
C- On désire autoriser les accès en
écriture simultanément avec les accès en lecture pour un
même compte. Y a-t-il une difficulté ? Justifiez votre
raisonnement.
D- On désire rajouter une opération qui
permet d’obtenir les soldes d’un ensemble de comptes, par exemple
tous les comptes d’un même client. Son pseudo code est le
suivant.
procédure Donner_Les_Soldes (Nb, Numéro_Compte[], var Solde[])
début -- lecture dans le fichier Fichier_Compte
-- des soldes des comptes du tableau Numéro_Compte
pour I de 1 à Nb faire
Lire(Fichier_Compte, Numéro_Compte[I], solde_compte);
Solde[I] := solde_compte;
fait ;
fin
Quelle
difficulté y a-t-il à permettre les accès en
écriture simultanément à l’exécution de cette
opération ? Comment peut-on résoudre cette
difficulté ?
Solution de l’exercice
4.10
4.10.1. Question A
Supposons que deux processus P1 et P2 exécutent, chacun
de leur côté, la même opération
CredDeb_Compte (10, créditer, 100).
Le déroulement de ces opérations peut être les
suivant :
P1 P2
lecture du compte 10
=> solde_compte = 1000
lecture compte 10
=> solde_compte = 1000
calcul
solde_compte = 1100
écriture compte 10
le solde sur disque vaut 1100
calcul
solde_compte =1100
écriture compte 10
le solde disque vaut 1100
Le
solde final sur disque vaut 1100 au lieu de
1200.
4.10.2. Question B
Pour palier cette difficulté, il faut insérer
Verrouiller (Fichier_Compte) au
début de la procédure
CredDeb_Compte, et
Deverrouiller (Fichier_Compte) à la
fin de CredDeb_Compte.
Dans l’exemple ci-dessus, le verrouillage par P1 avant
la lecture du compte interdira à P2 de lire le compte tant que P1 ne
l’a pas libéré, donc après la
réécriture du compte (valeur 1100). P2 sera alors
libéré, et verra le compte modifié par P1, donc la valeur
1100, et il réécrira la nouvelle valeur 1200
ensuite.
4.10.3. Question C
La lecture du solde simultané aux écritures ne
posent pas de difficulté particulière : le processus qui
exécute
Donner_Solde verra la valeur
du solde soit avant soit après la modification par
l’écrivain, comme si l’exécution complète du
processus avait eu lieu avant le début ou après la fin
d’exécution de
l’écrivain.
4.10.4. Question D
Cette fois, l’écrivain peut venir modifier un
compte déjà lu (le premier du tableau par exemple) et un autre qui
sera lu plus tard (le dernier du tableau par exemple). Si l’action de
l’écrivain consiste à débiter 1000 F du premier
compte et créditer 1000 F au deuxième compte, le débit
ne sera pas vu par Donner_Les_Soldes mais le crédit le sera. Le client
apparaîtra plus riche de 1000 F qu’il ne l’est en
réalité.
Pour résoudre ce problème, il suffit de
verrouiller le fichier au début de Donner_Les_Soldes et de le
déverrouiller à la fin. Ce verrouillage, s’il résout
le problème est plus fort que nécessaire, car il interdit
plusieurs exécutions de Donner_Les_Soldes en parallèles alors
qu’elles peuvent avoir lieu sans problème puisque
l’opération ne modifie pas les comptes. Pour le permettre, il
faudrait mettre en œuvre le schéma
lecteur-rédacteur.