Vous êtes sur la page 1sur 21

Cours système base de données

Transactions dans les bases de données : Les transactions sont des unités de programme qui accèdent à
la base de données en effectuant des opérations de lecture et/ou d'écriture. Le but des transactions est
de garantir que toutes les opérations dans une transaction sont exécutées avec succès ou aucune d'entre
elles n'est exécutée, afin de maintenir l'intégrité des données de la base de données.
Début et fin de transaction : Une transaction commence par le mot-clé BEGIN et se termine par
COMMIT ou ROLLBACK. Le BEGIN marque le début de la transaction, et COMMIT indique que la
transaction a réussi et que les modifications doivent être enregistrées de manière permanente dans la
base de données. En revanche, ROLLBACK annule toutes les opérations de la transaction et ramène la
base de données à son état précédent.
Exemple d'une transaction : L'exemple fourni illustre une transaction. Dans ce cas, il y a deux tables,
"EMP" et "DEPT", représentant des employés et des départements. La transaction débute par BEGIN
TRANSACTION, puis elle effectue deux opérations d'insertion de données. Elle ajoute un nouvel
employé à la table "EMP" et crée un nouveau département dans la table "DEPT". Enfin, la transaction
se termine par COMMIT.
Validation de la transaction : La transaction dans l'exemple est validée, car elle s'exécute avec succès
et laisse la base de données dans un état cohérent. Toutes les modifications apportées sont
permanentes. Cependant, il est important de noter que si quelque chose ne se passe pas comme prévu
au cours de la transaction, vous avez la possibilité d'annuler toutes les opérations en utilisant
ROLLBACK.
Les propriétés ACID sont un ensemble de caractéristiques essentielles dans le domaine des bases de
données et des systèmes de gestion de transactions. Elles garantissent la fiabilité et l'intégrité des
transactions informatiques. Voici une explication détaillée de chaque propriété ACID :
Atomicité (A - Atomicity) :
L'atomicité garantit que toute transaction est traitée comme une unité indivisible.
Une transaction est exécutée complètement ou pas du tout. Si une partie de la transaction échoue,
toutes les opérations effectuées jusqu'à ce point sont annulées.
Par exemple, si une transaction comprend plusieurs opérations, toutes ces opérations doivent réussir
pour que la transaction soit validée. Si l'une d'entre elles échoue, la transaction est annulée, et aucune
modification n'est conservée.
Cohérence (C - Consistency) :
La cohérence garantit que chaque transaction amène le système d'un état valide à un autre état valide.
Avant le début de la transaction, la base de données est dans un état valide, et après l'exécution de la
transaction, elle doit rester dans un état valide.
Cela signifie que les contraintes et les règles d'intégrité de la base de données doivent être respectées
en tout temps.
Isolation (I - Isolation) :
L'isolation assure que chaque transaction est exécutée comme si elle était la seule transaction sur le
système.
Aucune dépendance ou interférence n'est autorisée entre les transactions concurrentes.
L'objectif est de garantir que l'exécution simultanée de transactions produit le même résultat que si ces
transactions étaient exécutées en série.
Les transactions s'exécutent en isolation totale, ce qui signifie que si deux transactions, par exemple T1
et T2, s'exécutent simultanément, elles ne doivent pas influencer mutuellement leurs résultats.
Chacune doit être indépendante de l'autre.
Durabilité (D - Durability) :
La durabilité assure que les résultats d'une transaction validée sont enregistrés de manière permanente,
même en cas de défaillance du système.
Une fois qu'une transaction a été confirmée (par COMMIT), ses effets sont persistants et ne sont pas
perdus, même en cas de panne de courant, de panne matérielle ou d'autres problèmes.
Cela garantit que les données restent disponibles et intactes à long terme, ce qui est essentiel pour la
préservation de l'intégrité des données.
En résumé, les propriétés ACID assurent que les transactions sont traitées de manière fiable,
préservant l'intégrité des données et garantissant que les résultats des transactions sont cohérents,
indépendants les uns des autres, et durables, même en cas de problèmes. C'est un ensemble de normes
fondamentales pour les systèmes de gestion de bases de données et les applications nécessitant une
gestion rigoureuse des transactions.
États d'une Transaction :
Active : Une transaction entre dans cet état au début de son exécution. Pendant cet état, des opérations
de lecture ou d'écriture peuvent être effectuées.
Partiellement Validée : Une transaction entre dans cet état après la fin de l'exécution de toutes ses
opérations. Cependant, elle n'a pas encore été validée (confirmée) par un COMMIT.
Échec : Une transaction est considérée comme ayant échoué en cas de violation des règles de
cohérence, d'une erreur de vérification ou si la transaction est abandonnée alors qu'elle est encore dans
l'état actif.
Avortée : Une transaction entre dans cet état lorsque la transaction est annulée (rollback) en raison
d'une erreur ou d'un abandon.
Validée : Une transaction est validée après l'exécution réussie de la dernière opération, et elle est
confirmée à l'aide de la commande COMMIT.
Problèmes liés à l'exécution concurrente de transactions :
Problème de Perte de Modification : Lorsque deux transactions accèdent au même élément de la base
de données, et que l'exécution de leurs opérations se chevauche, des modifications peuvent être
perdues. Par exemple, si deux transactions essaient de modifier la même donnée simultanément, l'une
des modifications peut être écrasée par l'autre.
Problème de Non-Reproductibilité des Lectures : Lorsqu'une transaction réalise une opération
d'agrégation pendant qu'une autre transaction modifie des enregistrements, les résultats des lectures
peuvent varier. Par exemple, si une transaction lit une valeur X après qu'une autre transaction a
soustrait N à X et lit Y avant que N ne soit soustrait à Y, les résultats peuvent ne pas être cohérents.
Problème de Modification Temporaire : Si une transaction modifie un élément de la base de données,
mais échoue avant de confirmer la modification (avant COMMIT), un autre processus peut accéder à
l'élément mis à jour avant que la transaction initiale ne soit réparée, ce qui peut entraîner des
incohérences.

Contrôle de la Concurrence :
Le contrôle de la concurrence est un mécanisme qui permet aux transactions d'interagir les unes avec
les autres tout en préservant l'intégrité de la base de données. Il garantit que les problèmes liés à
l'exécution concurrente, tels que ceux mentionnés ci-dessus, sont gérés de manière appropriée.

1/ La concurrence dans une base de données se réfère au fait que plusieurs transactions (par exemple,
des opérations de lecture ou d'écriture de données) peuvent s'exécuter en même temps. Cela peut être
bénéfique pour plusieurs raisons :
Meilleure utilisation du processeur : Lorsque plusieurs transactions sont en cours d'exécution en même
temps, cela signifie que le processeur de l'ordinateur peut être utilisé de manière plus efficace. Une
transaction peut utiliser le processeur pendant qu'une autre attend par exemple l'accès au disque dur.
Cela signifie que le processeur n'est pas inactif et peut effectuer davantage de travail.
Réduction du temps de réponse : La concurrence permet également de réduire le temps de réponse des
transactions. Imaginez que vous ayez une transaction longue qui prend du temps pour s'exécuter. Si
une autre transaction courte doit être exécutée, elle ne devra pas attendre la fin de la transaction
longue. Cela signifie que la transaction courte peut être traitée plus rapidement, ce qui améliore
l'efficacité du système.
Le contrôle de la concurrence est essentiel pour gérer ces situations. Il s'agit de mettre en place des
mécanismes qui permettent aux transactions d'interagir tout en maintenant l'intégrité de la base de
données. Cela garantit que les transactions ne se bousculent pas les unes les autres et que les données
restent cohérentes et correctes.
Ordonnancement :
Un ordonnancement est une séquence chronologique spécifiant l'ordre d'exécution des opérations de
plusieurs transactions. L'ordonnancement est utilisé pour déterminer comment les transactions
interagissent et pour éviter des problèmes tels que la perte de modifications, la non-reproductibilité des
lectures et les modifications temporaires.

En ce qui concerne l'ordonnancement (ou tri) dans une base de données, il s'agit de spécifier l'ordre
dans lequel les résultats des requêtes SQL sont renvoyés. Cela permet d'organiser les données de
manière à ce qu'elles soient plus faciles à comprendre ou à traiter. Par exemple, vous pouvez trier une
liste de noms de clients par ordre alphabétique croissant pour la rendre plus lisible. L'ordonnancement
est un outil utile pour organiser les données dans une base de données.
Note important
Important : Dans la programmation concurrente et la gestion des transactions, lorsqu'une variable est
lue à partir de la mémoire à l'aide de l'instruction Lire, la valeur actuelle de cette variable est
récupérée. Cependant, avant d'exécuter l'instruction Ecrire pour mettre à jour la valeur de la variable,
d'autres transactions peuvent avoir la possibilité de modifier la valeur de la variable dans la mémoire.
Ainsi, la valeur de la variable peut changer entre la lecture et l'écriture, en fonction des opérations
effectuées par d'autres transactions concurrentes.
Cela implique que la cohérence des données doit être prise en compte dans la programmation
concurrente. Les mécanismes de synchronisation, tels que les verrous ou les transactions atomiques,
sont utilisés pour garantir que les modifications des variables sont correctement gérées et que
l'intégrité des données est préservée dans un environnement concurrent.

Ordonnancement = schuedule = ordre


L'ordonnancement O3 décrit comment les instructions des transactions T1 et T2 s'exécutent en
intercalant leurs opérations. Il est dit "équivalent à hT1, T2i" ce qui signifie qu'il représente une
exécution où les instructions de T1 et T2 s'entremêlent ou se chevauchent dans le temps, et cette
séquence d'exécution est équivalente à l'exécution séquentielle des transactions T1 et T2 l'une après
l'autre.
Pour mieux comprendre, examinons cet ordonnancement O3 étape par étape :
Lire(A) : T1 commence par lire la valeur de la variable A.
Lire(A) : T2 commence également par lire la valeur de la variable A.
A := A - 1000 : T1 effectue une opération de soustraction sur la valeur d'A.
T emp := A * 0,1 : T2 effectue une multiplication sur la valeur lue précédemment d'A, stocke le
résultat dans une variable temporaire "T emp".
A := A - T emp : T1 effectue une autre opération de soustraction sur la valeur d'A, utilisant le résultat
de la multiplication de T2.
Ecrire(A) : T1 écrit la nouvelle valeur d'A.
Lire(B) : T2 passe à la variable B, lit sa valeur actuelle.
B := B + 1000 : T2 effectue une opération d'addition sur la valeur de B.
Lire(B) : T1 revient à la variable B, lit sa valeur.
B := B + T emp : T2 ajoute la valeur stockée dans "Temp" (le résultat de sa multiplication précédente)
à la valeur de B.
Ecrire(B) : T2 écrit la nouvelle valeur de B.
Ce scénario représente une exécution "entrelacée" des transactions T1 et T2, où les instructions de
chaque transaction s'exécutent l'une après l'autre en alternance. L'ordre exact des opérations dépend de
la programmation concurrente et de l'ordonnancement du système.

Ordonencement serialisable
un ordonnancement est dit "sérialisable" lorsqu'il est possible de trouver une autre combinaison des
opérations des transactions qui donne le même résultat final, tout en maintenant la cohérence de la
base de données. Cela garantit que, quelle que soit la manière dont les transactions sont exécutées (de
manière concurrente ou dans un ordre différent), le résultat final est équivalent à une exécution
séquentielle des transactions, préservant ainsi l'intégrité des données dans la base de données. La
sérialisabilité est un concept clé en gestion de transactions pour assurer la cohérence des données dans
un environnement de base de données concurrentiel.Haut du formulaire
Un ordonnancement entrelacé est dit "sérialisable" s'il est équivalent à un ordonnancement sériel.
Expliquons cela en utilisant deux transactions, T1 et T2.
Supposons que nous ayons deux transactions, T1 et T2, et que nous examinions un ordonnancement
entrelacé entre elles :
Transaction T1:
Lire(A)
A := A - 100
Ecrire(A)
Transaction T2: 4. Lire(B)
B := B + 100
Ecrire(B)
L'ordonnancement entrelacé de ces transactions peut être le suivant :
T1 (1) - Lire(A)
T2 (4) - Lire(B)
T2 (5) - B := B + 100
T1 (2) - A := A - 100
T2 (6) - Ecrire(B)
T1 (3) - Ecrire(A)
Cet ordonnancement entrelacé est une combinaison des opérations de T1 et T2, et il peut sembler
chaotique à première vue. Cependant, il est sérialisable si l'on peut trouver un ordonnancement sériel
équivalent qui donnerait les mêmes résultats, c'est-à-dire qu'il préserve la cohérence de la base de
données.
Un ordonnancement en série de T1 et T2 pourrait être le suivant :
T1 (1) - Lire(A)
T1 (2) - A := A - 100
T1 (3) - Ecrire(A)
T2 (4) - Lire(B)
T2 (5) - B := B + 100
T2 (6) - Ecrire(B)
Cet ordonnancement en série effectue d'abord toutes les opérations de T1, puis toutes celles de T2.
L'ordonnancement entrelacé précédent, bien que dans un ordre différent, aboutit au même état de la
base de données. Par conséquent, il est sérialisable.
La sérialisabilité est un concept important en gestion de transactions, car elle garantit que, même si les
transactions s'exécutent en parallèle ou dans un ordre différent, le résultat final est équivalent à une
exécution séquentielle des transactions, ce qui préserve la cohérence de la base de données.
Un ordonnancement O est considéré sérialisable s'il produit le même résultat que l'exécution des
transactions T1, ..., Tn dans un ordre quelconque, c'est-à-dire, si quel que soit l'ordre dans lequel les
transactions sont exécutées, le résultat final est le même.

La c-sérialisabilité
La c-sérialisabilité (ou conflict-serializability) est un concept dans la gestion de transactions qui se
concentre sur les conflits entre les opérations de différentes transactions. Un ordonnancement est c-
sérialisable s'il est équivalent à un ordonnancement en série, ce qui signifie que les opérations de
toutes les transactions peuvent être réorganisées pour donner le même résultat qu'une exécution
séquentielle des transactions.
Pour déterminer si un ordonnancement est c-sérialisable, on examine les conflits entre les opérations
de différentes transactions. Un conflit se produit lorsqu'il y a au moins une opération d'écriture dans
une transaction et qu'une autre transaction lit ou écrit la même donnée. Pour qu'il n'y ait pas de conflit,
deux transactions peuvent lire la même donnée sans problème, mais dès qu'une transaction écrit, cela
crée un conflit avec toutes les opérations de lecture et d'écriture ultérieures concernant la même
donnée.
Voici un exemple simple pour illustrer la c-sérialisabilité :
Supposons que nous ayons deux transactions, T1 et T2, travaillant sur deux objets, A et B.
Transaction T1:
Lire(A)
Écrire(B)
Transaction T2: 3. Lire(B)
Écrire(A)
L'ordonnancement est le suivant :
T1 (1) - Lire(A)
T2 (3) - Lire(B)
T1 (2) - Écrire(B)
T2 (4) - Écrire(A)
L'ordonnancement ci-dessus n'est pas c-sérialisable, car il y a un conflit entre les opérations d'écriture
de T1 et T2 sur les objets A et B. Pour être c-sérialisable, il devrait exister un réarrangement des
opérations qui respecte l'ordre de sérialisation (l'ordre d'exécution en série des transactions) tout en
éliminant les conflits. Dans cet exemple, un ordonnancement c-sérialisable serait celui où T1 s'exécute
avant T2 ou T2 s'exécute avant T1, mais pas les deux en parallèle.
La c-sérialisabilité est un concept important pour garantir la cohérence des données dans les systèmes
de gestion de bases de données, car elle permet de s'assurer que l'exécution concurrente des
transactions n'introduit pas d'incohérences dans les données.
Read et write ils influent sur la base de donnees
Conflits dans les opérations : Les conflits se produisent lorsque deux opérations de transactions
différentes interagissent sur la même donnée. Les conflits peuvent être de deux types principaux :
Lecture-Écriture (Read-Write) : Un conflit de lecture-écriture se produit lorsqu'une transaction lit une
donnée tandis qu'une autre transaction l'écrit simultanément.
Écriture-Écriture (Write-Write) : Un conflit d'écriture-écriture se produit lorsqu'une transaction écrit
une donnée qui est également écrite par une autre transaction en même temps.
Conflit-Équivalence : Deux exécutions (ordonnancements) sont considérées comme conflit-
équivalentes si elles répondent aux critères suivants :
Elles comportent les mêmes opérations (lectures et écritures).
Chaque paire d'opérations en conflit (c'est-à-dire qui interagissent sur la même donnée) est dans le
même ordre dans les deux exécutions.
Conflit-Sérialisabilité : Une exécution est considérée comme conflit-sérialisable si elle est équivalente
à une exécution en série. Cela signifie que l'exécution concurrente des transactions est équivalente à
une exécution où les transactions sont exécutées l'une après l'autre, dans un ordre sériel.
Exemple :
T1 lit A.
T2 lit B.
T1 écrit B.
T2 écrit A.
Nous pouvons voir que T1 lit la valeur A, que T2 lit la valeur B, et que chaque transaction écrit la
valeur lue dans l'autre variable. Les lectures et écritures se chevauchent, ce qui peut entraîner une
incohérence des données.
Pour qu'une exécution soit considérée comme conflit-sérialisable, il doit exister un ordre sériel dans
lequel les transactions peuvent être exécutées sans conflits. Dans cet exemple, si nous exécutons
d'abord T1, puis T2 (ou vice versa), les transactions ne se chevauchent pas et les données restent
cohérentes. Ainsi, cette exécution concurrente est considérée comme conflit-sérialisable.

En d'autres termes, une exécution est considérée comme conflit-sérialisable si les conflits entre les
opérations de différentes transactions sont gérés de manière à préserver la cohérence des données, et si
cette exécution pourrait être réorganisée de manière à obtenir le même résultat qu'une exécution
séquentielle des transactions.
La c-sérialisabilité est un mécanisme essentiel pour garantir la cohérence des données dans les bases
de données lorsqu'il y a des transactions concurrentes, et elle permet de s'assurer que les opérations sur
les données respectent l'ordre souhaité, évitant ainsi les incohérences.
Contrôle de concurrence
Notion de verrouillage
Une solution générale à la gestion de la concurrence est une technique très simple appelée
verrouillage.
Définition verrou :
Poser un verrou sur un objet (typiquement un tuple) par une transaction signifie rendre cet objet
inaccessible aux autres transactions.
Synonymes : Lock
Définition verrou partagé :
Un verrou partagé, noté P, est posé par une transaction lors d’un accès en lecture sur cet objet.
Un verrou partagé interdit aux autres transaction de poser un verrou exclusif sur cet objet et donc d’y
accéder en écriture.
Synonymes : verrou de lecture, Read lock.
Définition verrou exclusif :
Un verrou exclusif, noté X, est posé par une transaction lors d’un accès en écriture sur cet objet.
Un verrou exclusif interdit aux autres transactions de poser tout autre verrou (partagé ou exclusif) su
cet objet et donc d’y accéder (ni en lecture, ni en écriture).
Synonymes : Verrou d’écriture, Exclusive lock.
Les demandes de verrous sont adressées au gestionnaire de la concurrence. Une transaction ne peut
avancer tant que le verrou qu’elle demande ne lui est pas attribué.
Règles de verrouillage :
Soit la transaction A voulant poser un verrou P sur un objet O :
o Si O n’est pas verrouillé alors A peut poser un verrou P.
o Si O dispose déjà d’un ou plusieurs verrous P alors A peut poser un verrou P o Si O dispose déjà
d’un verrou X alors A ne peut pas poser un verrou P. Soit la transaction A voulant poser un verrou X
sur un objet O :
o Si O n’est pas verrouillé alors A peut poser un verrou X.
o Si O dispose déjà d’un ou plusieurs verrous P ou d’un verrou X alors A ne peut pas poser de verrou
X.

La notion de verrouillage, également connue sous le nom de "verrouillage" ou "lock" en anglais, est
une technique utilisée pour gérer la concurrence lors de l'accès à des objets partagés dans un système
de gestion de bases de données ou dans des applications multi-utilisateurs. Les verrous permettent de
contrôler l'accès concurrentiel aux objets en garantissant que certaines transactions peuvent les utiliser
en lecture ou en écriture tout en empêchant d'autres transactions d'accéder simultanément à ces objets.
Voici quelques exemples pour illustrer les concepts de verrouillage, de verrou partagé (P), et de verrou
exclusif (X) :
Exemple 1 : Verrou partagé (P)
Supposons qu'il existe une base de données contenant des informations sur les comptes bancaires.
Plusieurs utilisateurs peuvent accéder à ces comptes en même temps. Une transaction A souhaite lire le
solde d'un compte particulier (accès en lecture). Pour ce faire, la transaction A pose un verrou partagé
(P) sur le compte concerné. Tant que le verrou partagé est maintenu, d'autres transactions peuvent
également poser des verrous partagés pour lire le même compte, mais elles ne peuvent pas poser de
verrous exclusifs pour modifier le compte.
Transaction A pose un verrou P sur le compte C1.
Transaction B peut également poser un verrou P sur le compte C1 pour lire son solde.
Transaction C ne peut pas poser de verrou X sur le compte C1 tant que le verrou P est présent.
Exemple 2 : Verrou exclusif (X)
Toujours dans le contexte des comptes bancaires, supposons que la transaction D souhaite effectuer
une opération de dépôt sur un compte (accès en écriture). Pour cela, la transaction D pose un verrou
exclusif (X) sur le compte concerné. Tant que le verrou exclusif est maintenu, aucune autre transaction
ne peut poser un verrou partagé ou exclusif sur le même compte, car l'accès en écriture est réservé.
Transaction D pose un verrou X sur le compte C2 pour effectuer un dépôt.
Pendant ce temps, aucune autre transaction (par exemple, E) ne peut poser un verrou P ou X sur le
compte C2, car le verrou X est en place.
Exemple 3 : Combinaison de verrous
Une transaction F souhaite transférer de l'argent d'un compte vers un autre. Pour cela, elle pose un
verrou exclusif sur le compte source et un verrou partagé sur le compte de destination pour éviter que
d'autres transactions n'écrivent sur le compte source ou ne lisent de manière incorrecte le compte de
destination pendant la transaction de transfert.
Transaction F pose un verrou X sur le compte source C3 pour effectuer un retrait.
Elle pose également un verrou P sur le compte de destination C4 pour s'assurer que personne d'autre ne
le modifie pendant le transfert.
Pendant ce temps, aucune autre transaction ne peut poser de verrou X ou P sur C3 et aucun verrou X
ne peut être posé sur C4. Cependant, d'autres transactions peuvent poser des verrous P sur C4 pour des
lectures.
En résumé, les verrous permettent de contrôler l'accès concurrentiel aux objets partagés en suivant des
règles strictes pour éviter les conflits. Les verrous partagés permettent la lecture concurrente, tandis
que les verrous exclusifs garantissent un accès exclusif en écriture.
Le verrouillage à deux phases (2PL) est un protocole de gestion de la concurrence utilisé dans les
bases de données pour garantir la sérialisabilité des transactions. Il impose des règles strictes aux
transactions concernant l'acquisition et la libération de verrous. Le 2PL peut être divisé en deux phases
: une phase de croissance où la transaction acquiert des verrous et une phase de résorption où elle
libère ces verrous. Il existe deux variantes du 2PL : le 2PL strict et le 2PL rigoureux, qui imposent des
règles encore plus strictes.
Exemple de 2PL (Verrouillage à deux phases) :
Supposons que vous ayez une base de données contenant des informations sur des réservations de
billets d'avion. Plusieurs utilisateurs tentent d'effectuer des réservations simultanément, et vous devez
garantir l'intégrité des données et éviter les anomalies. Vous utilisez le 2PL pour gérer l'accès
concurrentiel.
Phase de croissance :
Transaction T1 souhaite réserver un siège sur un vol. Avant de pouvoir effectuer cette réservation, elle
doit acquérir un verrou exclusif (X) sur le siège concerné, par exemple, le siège 1 sur le vol 101.
T1 acquiert le verrou X sur le siège 1 du vol 101.
Transaction T2 souhaite réserver un siège sur le même vol, par exemple, le siège 2 sur le vol 101.
Avant de poursuivre, elle doit également acquérir un verrou X sur le siège 2.
T2 acquiert le verrou X sur le siège 2 du vol 101.
À ce stade, ni T1 ni T2 ne peuvent demander d'autres verrous, car ils sont dans la phase de croissance
et doivent acquérir tous les verrous nécessaires avant de libérer un seul verrou.
Phase de résorption :
Après avoir effectué la réservation, T1 libère le verrou sur le siège 1.
T1 libère le verrou X sur le siège 1 du vol 101.
T2 peut maintenant effectuer sa réservation du siège 2, car T1 a libéré le verrou correspondant.
Une fois que T2 a effectué sa réservation, elle libère le verrou X sur le siège 2.
T2 libère le verrou X sur le siège 2 du vol 101.
Les deux transactions ont terminé leur travail et ont libéré tous les verrous qu'elles avaient acquis, ce
qui permet à d'autres transactions d'accéder aux mêmes sièges en suivant le même protocole.
Le 2PL garantit que les transactions sont sérialisables, ce qui signifie que l'ordre d'exécution des
transactions donne un résultat équivalent à un ordre séquentiel, tout en respectant les règles strictes
d'acquisition et de libération des verrous. Cependant, le 2PL ne garantit pas l'absence de deadlocks ou
de cascades. Pour éviter ces situations, des mécanismes de détection et de résolution de deadlocks
peuvent être utilisés en combinaison avec le 2PL.
Haut du formulaire

Niveau d’isolation :

Les niveaux d'isolation des transactions sont un concept essentiel dans le domaine des bases de
données pour gérer la concurrence entre transactions concurrentes. Chaque niveau d'isolation définit le
degré de séparation entre les transactions et tente de prévenir les phénomènes indésirables qui peuvent
se produire lorsque plusieurs transactions s'exécutent en parallèle. Ces phénomènes indésirables sont :
Lecture impropre (Dirty Read) : Une transaction lit des données écrites par une transaction
concurrente qui n'a pas encore été validée. Cela peut entraîner des problèmes car les données lues
peuvent ne pas être définitives.
Lecture non reproductible (Non-Repeatable Read) : Une transaction relit des données qu'elle a déjà
lues précédemment, mais constate que ces données ont été modifiées par une autre transaction qui a
été validée depuis la première lecture. Cela peut entraîner une incohérence des données.
Lecture fantôme (Phantom Read) : Une transaction réexécute une requête qui renvoie un ensemble de
lignes satisfaisant une certaine condition de recherche, mais constate que l'ensemble de lignes a
changé en raison d'une autre transaction récemment validée. Cela peut également entraîner des
résultats incohérents.
Les niveaux d'isolation standard SQL définissent les degrés de séparation entre les transactions pour
prévenir ces phénomènes indésirables. Voici un résumé des différents niveaux d'isolation :
Niveau de non-isolation (Read Uncommitted) : Ce niveau n'offre aucune garantie d'isolation. Il permet
les trois types d'anomalies transactionnelles (lecture impropre, lecture non reproductible et lecture
fantôme). Les transactions peuvent accéder aux données sans attendre la validation des autres
transactions.
Niveau de lecture commise (Read Committed) : Ce niveau évite la lecture impropre (Dirty Read). Cela
signifie qu'une transaction ne peut pas lire les données non validées d'une autre transaction, mais elle
peut toujours être confrontée aux problèmes de lecture non reproductible et de lecture fantôme.
Niveau de répétabilité de lecture (Repeatable Read) : Ce niveau résout les problèmes de lecture
impropre et de lecture non reproductible. Une transaction ne peut lire que des données validées et
garantit que les données lues ne seront pas modifiées par d'autres transactions. Cependant, il ne
garantit pas l'absence de lectures fantômes.
Niveau de sérialisation (Serializable) : C'est le niveau le plus strict, garantissant l'absence des trois
anomalies transactionnelles. Une transaction en mode "sérialisable" s'exécute comme si elle était la
seule transaction dans le système, ce qui assure la cohérence complète des données.
Le choix du niveau d'isolation dépend des besoins de l'application. Des niveaux moins stricts, comme
"Read Committed," permettent une meilleure concurrence mais peuvent entraîner des anomalies. Les
niveaux plus stricts, comme "Serializable," garantissent la cohérence des données, mais peuvent
entraîner une concurrence moindre. Le niveau d'isolation doit être choisi en fonction des exigences de
cohérence et de performance de l'application.

SERIALIZABLE (2PL Rigoureux) :


Exemple : Supposons que deux transactions, T1 et T2, souhaitent effectuer des réservations sur un vol.
La transaction T1 réserve tous les sièges d'un vol en utilisant une opération d'INSERT. T2 tente
également de réserver des sièges sur le même vol.
Comportement : Dans le mode SERIALIZABLE, T1 obtient un verrou sur toute la table des sièges et
le maintient jusqu'à ce qu'elle valide (commit). T2 est bloquée jusqu'à ce que T1 libère le verrou.
Aucune modification de T2 n'est autorisée tant que T1 occupe un verrou exclusif sur la table des
sièges.
REPEATABLE READ (2PL Rigoureux, verrous sur les enregistrements) :
Exemple : Une transaction T1 lit un enregistrement (ligne) spécifique dans une table et obtient un
verrou exclusif sur cet enregistrement. Ensuite, une transaction T2 tente de lire le même
enregistrement.
Comportement : Dans le mode REPEATABLE READ, T1 obtient un verrou exclusif sur
l'enregistrement qu'elle lit. T2 est bloquée lorsqu'elle tente de lire le même enregistrement. Les verrous
exclusifs sur les enregistrements assurent que les données lues par T1 ne changent pas jusqu'à ce que
T1 ait validé.
READ COMMITTED (Verrous X sur les objets, libération des verrous P après la lecture) :
Exemple : T1 souhaite lire un ensemble de lignes d'une table. T2 souhaite mettre à jour l'une de ces
lignes pendant que T1 est en cours d'exécution.
Comportement : Dans le mode READ COMMITTED, T1 obtient des verrous partagés (P) sur les
lignes qu'elle lit. T2 peut obtenir un verrou exclusif (X) pour mettre à jour une ligne, mais T1 peut
toujours lire les autres lignes de la table. Après la lecture, T1 libère immédiatement les verrous P, ce
qui permet à T2 de mettre à jour d'autres lignes.
READ UNCOMMITTED (Lecture sans verrous P) :
Exemple : T1 effectue une lecture d'une table sans demander de verrous. T2 tente d'insérer des
données dans la même table pendant que T1 lit.
Comportement : Dans le mode READ UNCOMMITTED, T1 peut lire les données sans obtenir de
verrous P, ce qui signifie qu'elle ne bloque pas T2 même si T2 effectue une opération d'insertion en
même temps. Cela peut entraîner des problèmes de cohérence, car T1 peut lire des données en cours de
modification par T2.
SNAPSHOT (gestion des versions) :
Exemple : T1 lit une table à un certain moment, puis T2 met à jour des enregistrements pendant que
T1 est en cours d'exécution.
Comportement : Dans le mode SNAPSHOT, le système maintient plusieurs versions de la base de
données. T1 voit les données telles qu'elles étaient au moment où elle a commencé, indépendamment
des mises à jour par T2. Ainsi, T1 ne bloque pas T2, et les deux peuvent s'exécuter en parallèle sans
conflits.
Chaque niveau d'isolation a ses avantages et inconvénients en termes de cohérence des données et de
performances. Le choix du niveau dépend des besoins de l'application et des compromis entre la
concurrence et la cohérence des données.
Le protocole avec estampillage (ou "timestamping protocol") est une technique de gestion de la
concurrence dans les systèmes de gestion de bases de données. Il vise à ordonner strictement les
transactions en leur attribuant des estampilles temporelles (ou des numéros d'ordre) pour garantir
l'ordre d'exécution correct des transactions. Les estampilles sont utilisées pour déterminer l'ordre dans
lequel les transactions peuvent accéder aux données.
Voici une explication de ce protocole avec un exemple et des requêtes :
Principe de l'estampillage :
Lorsqu'une transaction T commence son exécution (Begin Of Transaction), elle reçoit une estampille
(timestamp) de l'ordonnanceur. Chaque estampille est un numéro unique qui représente l'ordre dans
lequel les transactions sont soumises à l'ordonnanceur.
Chaque granule de données (par exemple, une ligne dans une table) conserve une note de l'estampille
de la dernière transaction qui a accédé à ce granule.
Un granule n'accepte un nouvel accès que s'il est demandé par une transaction "plus jeune", c'est-à-dire
par une transaction avec un numéro d'estampille plus élevé que celui du dernier accès.
Exemple :
Supposons que nous ayons une table appelée "Comptes" contenant des informations sur les comptes
bancaires. Deux transactions, T1 et T2, souhaitent accéder à un même compte. Voici comment le
protocole avec estampillage fonctionne :
T1 commence avec l'estampille 1, et T2 commence avec l'estampille 2.
T1 souhaite effectuer une opération de retrait sur le compte C1. Le granule de données correspondant à
C1 note que la dernière transaction à l'avoir consulté avait l'estampille 0 (personne n'a encore consulté
ce compte).
Le granule de données accepte l'accès de T1, car son estampille (1) est plus grande que celle du dernier
accès (0).
T2 souhaite effectuer une opération de dépôt sur le même compte C1. Cependant, le granule de
données note que la dernière transaction à l'avoir consulté avait l'estampille 1 (T1).
Le granule de données refuse l'accès à T2, car son estampille (2) n'est pas plus grande que celle de la
dernière transaction (1).
T1 effectue son retrait, et le granule de données est mis à jour avec l'estampille 1.
Maintenant, T2 peut effectuer son dépôt, car l'estampille de T2 (2) est supérieure à la dernière
estampille (1).
Résumé :
Le protocole avec estampillage garantit un ordre strict d'accès aux données en fonction des estampilles
des transactions. Cela permet de prévenir les conflits de concurrence en attribuant des numéros d'ordre
et en s'assurant que les transactions plus jeunes n'accèdent pas aux données tant que les transactions
plus anciennes ne les ont pas relâchées. Ce protocole est utilisé pour garantir la sérialisabilité des
transactions dans un système de gestion de bases de données.
Ajouté le 11/11

Les niveaux d'isolation dans les bases de données SQL définissent comment les transactions
interagissent les unes avec les autres. Chaque niveau offre un équilibre différent entre la cohérence des
données, la prévention des anomalies de lecture et la performance. Voici une explication de chaque
niveau avec des exemples :
1. READ UNCOMMITTED
Description : Le niveau le plus bas, où une transaction peut lire des données modifiées par d'autres
transactions qui n'ont pas encore été validées (commit).
Exemple : Imaginez une transaction T1 qui modifie une donnée. Avant que T1 ne soit validée, une
autre transaction T2 peut lire cette donnée modifiée. Si T1 est annulée (rollback), T2 aura lu une
donnée qui n'existe finalement pas ("dirty read").
2. READ COMMITTED
Description : Les transactions ne peuvent lire que des données qui ont été validées. Cela empêche les
"dirty reads" mais peut toujours mener à des "non-repeatable reads" (lire des données différentes à
plusieurs reprises dans la même transaction car une autre transaction a modifié ces données entre-
temps).
Exemple : T1 lit une donnée. T2 modifie ensuite cette donnée et la valide. Si T1 relit la même donnée,
elle verra la version modifiée.
3. REPEATABLE READ
Description : Assure que si une transaction relit des données qu'elle a déjà lues, elle verra toujours la
même version. Cela est réalisé en conservant les verrous sur les données lues jusqu'à la fin de la
transaction. Cela peut toutefois mener à des "phantom reads".
Exemple : T1 lit un ensemble de données. T2 essaie de modifier ces données mais est bloquée jusqu'à
ce que T1 soit terminée. T1 relit les données et voit la même version qu'au début.
4. SERIALIZABLE
Description : Le niveau le plus élevé d'isolation. Les transactions sont traitées comme si elles étaient
exécutées séquentiellement. Cela prévient les "dirty reads", "non-repeatable reads" et les "phantom
reads", mais peut réduire la performance en raison de verrouillages plus stricts.
Exemple : T1 commence et lit ou modifie des données. Si T2 essaie d'accéder à ces mêmes données
(ou même à des données liées via des index), elle doit attendre que T1 soit complètement terminée.
Dans la pratique, les niveaux d'isolation supérieurs assurent une meilleure cohérence des données mais
peuvent diminuer la performance et augmenter le risque de blocages entre transactions. Le choix du
niveau d'isolation dépend du besoin de cohérence des données par rapport aux exigences de
performance de l'application.
Oracle 8 introduit le concept de multiversionnement pour gérer la cohérence des données et la
concurrence des transactions. Cette approche permet de maintenir plusieurs versions d'un même objet
dans la base de données, offrant ainsi une meilleure gestion des lectures et écritures concurrentes.
Voici une explication détaillée :
Multiversionnement dans Oracle 8
Lecture d'un objet (A) par une transaction (Ti) :
Lorsque Ti veut lire A, le système lui fournit la version de A dont l'horodatage de début (E ST(A)) est
le maximum, mais toujours inférieur à l'horodatage de début de Ti (ST(Ti)). Cela garantit que Ti lit une
version de A qui était "actuelle" au moment où Ti a commencé.
Écriture sur un objet (A) par Ti :
Si Ti veut écrire sur A et que l'horodatage de début de Ti (ST(Ti)) est supérieur ou égal à l'horodatage
de fin de la dernière transaction ayant modifié A (L ST(A)), alors une nouvelle version de A est créée.
L'horodatage de fin de cette nouvelle version (L ST(A)) est mis à jour pour correspondre à ST(Ti).
Reprise sur Panne et Accès aux Données
Pages disque et pages mémoire :
Les données sont stockées sous forme de pages, qui peuvent résider soit sur le disque soit en mémoire
centrale (MC). Le déplacement de ces pages entre le disque et la MC se fait via des procédures
spécifiques : Input(P) pour charger une page en mémoire et Output(P) pour écrire une page en
mémoire vers le disque.
Espace de travail privé des transactions :
Chaque transaction Ti dispose d'un espace de travail privé. Elle travaille sur des copies des objets de la
base de données, notées xi pour une copie de l'objet X manipulée par Ti.
Affectations entre X et xi :
Les opérations de lecture et d'écriture sur les objets de la base se font via les appels Lire(X) et
Ecrire(X). Ces appels gèrent le transfert des données entre l'objet original X dans la base de données et
sa copie xi dans l'espace de travail de Ti.
Opération Output(PX) :
L'opération Output(PX), qui écrit la page PX modifiée en mémoire vers le disque, n'est pas
nécessairement exécutée immédiatement après un appel à Ecrire(X). Cela permet une certaine
flexibilité dans la gestion de la mémoire et la planification des écritures sur le disque, optimisant ainsi
les performances et la gestion des ressources.
En résumé, Oracle 8 utilise le multiversionnement pour fournir un accès cohérent aux données dans un
environnement multi-utilisateur, tout en optimisant les performances et la reprise après panne. Cette
approche minimise les conflits de verrouillage et améliore la concurrence en permettant aux
transactions de travailler sur des versions distinctes d'un même objet.

Dans le contexte de la gestion des bases de données, la reprise après un crash est un aspect crucial.
L'exemple donné illustre comment les transactions sont gérées et récupérées en utilisant un système de
journalisation (ou "Log"). Voici une explication détaillée :
Contexte de la Reprise après Crash
Journalisation des Transactions :
Les systèmes de bases de données maintiennent un journal (Log) des actions de chaque transaction. Ce
journal contient des enregistrements comme hTiStarti (début de la transaction Ti) et hTiCommiti
(validation de la transaction Ti).
Critère de Reprise :
Une transaction doit être refaite (opération Redo) lors de la reprise après un crash si à la fois son
enregistrement de début et de validation (commit) sont présents dans le journal. Cela signifie que la
transaction a été validée mais que ses modifications peuvent ne pas avoir été entièrement écrites sur le
disque.
Exemple Expliqué
Transactions T0 et T1 :
T0 :
Lit la valeur de A (Lire(A)).
Modifie A (A := A - 50).
Écrit la nouvelle valeur de A dans la base de données (Ecrire(A)).
Lit la valeur de B (Lire(B)).
Modifie B (B := B + 50).
Écrit la nouvelle valeur de B (Ecrire(B)).
T1 :
Lit la valeur de C (Lire(C)).
Modifie C (C := C - 100).
Écrit la nouvelle valeur de C (Ecrire(C)).
Processus de Reprise :
Supposons qu'un crash se produit après ces opérations. Lors de la reprise, le système vérifie le journal.
Si les entrées de début et de fin (commit) pour T0 et T1 sont présentes dans le journal, cela signifie
que ces transactions ont été validées mais pas nécessairement écrites en totalité sur le disque.
Le système effectue alors Redo(T0) et Redo(T1), en appliquant les modifications enregistrées dans le
journal pour ces transactions sur la base de données. Cela garantit que les modifications de T0 et T1
sont correctement reflétées dans la base de données, même après le crash.
En résumé, l'exemple illustre comment un système de base de données utilise un journal pour s'assurer
que toutes les transactions validées sont correctement appliquées à la base de données, même en cas de
crash. Cela garantit l'intégrité et la cohérence des données.
La configuration du journal (Log) de transactions à trois instants différents nous donne une vue
d'ensemble sur l'état des transactions T0 et T1 et sur les actions à entreprendre en cas de panne à ces
différents instants. Voici l'explication de chaque cas :
Configuration du Log
Instant (a) :
Contenu du Log : hT0starti, hT0, A, 950i, hT0, B, 2050i.
À ce stade, la transaction T0 a commencé et effectué des modifications sur A et B, mais elle n'a pas
encore été validée (commit).
En cas de panne : Comme il n'y a pas de commit pour T0, il n'y a pas besoin de faire un redo (refaire
les modifications) de T0. Les modifications de T0 ne sont pas considérées comme définitives.
Instant (b) :
Contenu du Log : hT0starti, hT0, A, 950i, hT0, B, 2050i, hT0commiti, hT1starti.
Ici, T0 a été validée (commit), et T1 a commencé mais n'a pas encore effectué de modifications.
En cas de panne : Il est nécessaire de faire un redo de T0 car elle a été validée. Les modifications de
T0 sur A et B doivent être réappliquées pour assurer la cohérence des données.
Instant (c) :
Contenu du Log : hT0starti, hT0, A, 950i, hT0, B, 2050i, hT0commiti, hT1starti, hT1, C, 600i,
hT1commiti.
T0 et T1 ont toutes les deux été validées, avec des modifications sur A, B, et C.
En cas de panne : Il est nécessaire de faire un redo à la fois pour T0 et T1, dans cet ordre, car les deux
transactions ont été validées. Cela garantit que toutes les modifications apportées par ces transactions
sont correctement reflétées dans la base de données.
Résumé
À l'instant (a), aucun redo n'est nécessaire car aucune transaction n'a été validée.
À l'instant (b), un redo est nécessaire pour T0 car elle a été validée.
À l'instant (c), des redos sont nécessaires pour T0 et T1, dans cet ordre, car les deux ont été validées.
Cette gestion des transactions via un journal est cruciale pour assurer l'intégrité des données en cas de
panne. Elle permet de reconstruire l'état correct de la base de données en réappliquant les transactions
validées.
La gestion des transactions dans une base de données, notamment la reprise après un crash et la
gestion de la concurrence, est un sujet complexe. Je vais essayer de simplifier les concepts en utilisant
des exemples faciles à comprendre.
Opérations undo et redo
undo(Ti):
Utilisée pour annuler les effets d'une écriture non validée.
Par exemple, si une transaction T1 commence, modifie une valeur A de 100 à 110, mais n'est pas
validée (commit) avant un crash, undo(T1) rétablira A à sa valeur originale de 100.
redo(Ti):
Utilisée pour réappliquer les effets d'une écriture validée.
Par exemple, si une transaction T2 commence, modifie B de 200 à 210, et est validée, redo(T2)
s'assurera que B est bien à 210 après un redémarrage suite à un crash.
Exemple de Reprise
undo et redo en action :
Supposons les transactions suivantes :
T0 démarre, modifie A de 1000 à 950, modifie B de 2000 à 2050, puis se valide.
T1 démarre et modifie C de 700 à 600, mais n'est pas encore validée.
En cas de crash :
(a) Si le crash survient avant le commit de T0, undo(T0) est nécessaire pour ramener A et B à leurs
valeurs originales.
(b) Si le crash survient après le commit de T0 mais avant celui de T1, redo(T0) est nécessaire pour
assurer que les modifications de T0 sont appliquées, tandis que undo(T1) annule les modifications non
validées de T1.
(c) Si le crash survient après les commits de T0 et T1, redo(T0) et redo(T1) sont nécessaires dans cet
ordre pour réappliquer leurs modifications.
Points de Reprise (Checkpoint)
Utilité des Checkpoints :
Pour éviter de devoir parcourir l'intégralité du log lors d'une reprise, des points de reprise (checkpoint)
sont régulièrement insérés. Ils marquent un état stable de la base de données.
Lors de la reprise, on commence à partir du dernier checkpoint, ce qui réduit le nombre de transactions
à considérer pour undo et redo.
Exemple avec Checkpoint :
Supposons qu'un checkpoint a été inséré après la validation de T2 mais avant le début de T3.
En cas de crash après ce checkpoint :
T1 et T2, commencées et validées avant le checkpoint, ne nécessitent pas d'action.
T3, commencée après le checkpoint, nécessite un undo si elle n'a pas été validée ou un redo si elle l'a
été.
Gestion de la Concurrence
Protocole de verrouillage en deux phases strict :
Assure que les modifications des transactions non encore validées restent invisibles aux autres
transactions.
Exemple en Présence de la Concurrence :
Supposons T1 et T2 travaillant sur différentes parties de la base de données et un checkpoint est inséré
pendant leur exécution.
En cas de crash :
Si T1 est validée avant le crash, redo(T1) est nécessaire.
Si T2 n'est pas validée, undo(T2) est nécessaire pour annuler ses modifications.
Conclusion
La reprise après crash dans les bases de données implique l'utilisation d'opérations undo pour annuler
les transactions non validées et redo pour réappliquer les transactions validées. Les checkpoints
réduisent la quantité de travail nécessaire lors de la reprise. La gestion de la concurrence assure que les
transactions interagissent de manière cohérente et isolée.

Vous aimerez peut-être aussi