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.