Concomitance et cohérence des données

Le contenu du script de cette page a pour seul objectif la navigation et n'altère en rien le contenu.

Ce chapitre explique comment Oracle AI Database gère des données cohérentes dans un environnement de base de données multiutilisateur.

Présentation de la simultanéité et de la cohérence des données

Dans une base de données mono-utilisateur, un utilisateur peut modifier des données sans se soucier que d'autres utilisateurs modifient les mêmes données en même temps. Toutefois, dans une base de données multiutilisateur, les instructions de transactions simultanées multiples peuvent mettre à jour les mêmes données. Les transactions exécutées simultanément doivent produire des résultats significatifs et cohérents.

Une base de données multiutilisateur doit fournir les éléments suivants :

Pour décrire un comportement de transaction cohérent lorsque les transactions sont exécutées simultanément, les chercheurs en bases de données ont défini un modèle d'isolement des transactions appelé serializability. Une transaction sérialisable fonctionne dans un environnement qui la fait apparaître comme si aucun autre utilisateur ne modifiait les données de la base.

Bien que ce degré d'isolement entre les transactions soit généralement souhaitable, l'exécution de nombreuses applications en mode sérialisable peut sérieusement compromettre le débit des applications. L'isolement complet des transactions en cours d'exécution simultanée peut signifier qu'une transaction ne peut pas effectuer une insertion dans une table faisant l'objet d'une requête par une autre transaction. En bref, les considérations du monde réel nécessitent généralement un compromis entre l'isolation parfaite des transactions et les performances.

Oracle AI Database maintient la cohérence des données en utilisant un modèle de cohérence multiversion et divers types de verrous et de transactions. Ainsi, la base de données peut présenter une vue des données à plusieurs utilisateurs simultanés, chaque vue étant cohérente jusqu'à un point dans le temps. Etant donné que différentes versions des blocs de données peuvent exister simultanément, les transactions peuvent lire la version des données validées au moment requis par une interrogation et renvoyer des résultats cohérents à un seul moment dans le temps.

Cohérence de lecture multiversion

Dans Oracle AI Database, le multiversion est la possibilité de matérialiser simultanément plusieurs versions des données. Oracle AI Database maintient la cohérence en lecture multiversion.

Les requêtes d'une base de données Oracle présentent les caractéristiques suivantes :

Cohérence de lecture au niveau instruction

Oracle AI Database applique toujours la cohérence de lecture au niveau de l'instruction, ce qui garantit que les données renvoyées par une seule requête sont validées et cohérentes pour un seul point dans le temps.

Le moment auquel une instruction SQL est cohérente dépend du niveau d'isolement de la transaction et de la nature de l'interrogation :

Voir aussi : Guide de développement Oracle AI Database pour en savoir plus sur Flashback Query

Cohérence de lecture au niveau transaction

Oracle AI Database peut également assurer la cohérence en lecture de toutes les requêtes d'une transaction, appelée cohérence en lecture au niveau de la transaction.

Dans ce cas, chaque instruction d'une transaction voit les données du même point dans le temps. C'est l'heure à laquelle la transaction a commencé.

Les requêtes effectuées par une transaction sérialisable voient les modifications apportées par la transaction elle-même. Par exemple, une transaction qui met à jour employees, puis interroge employees verra les mises à jour. La cohérence en lecture au niveau de la transaction produit des lectures reproductibles et n'expose pas une requête à des lectures fantômes.

Cohérence de lecture et segments d'annulation

Pour gérer le modèle de cohérence en lecture multiversion, la base de données doit créer un ensemble de données cohérent en lecture lorsqu'une table est interrogée et mise à jour simultanément.

Oracle AI Database assure la cohérence en lecture grâce aux données d'annulation.

Chaque fois qu'un utilisateur modifie des données, Oracle AI Database crée des entrées d'annulation, qu'il écrit dans des segments d'annulation. Les segments d'annulation contiennent les anciennes valeurs des données qui ont été modifiées par des transactions non validées ou récemment validées. Ainsi, plusieurs versions des mêmes données, toutes à des moments différents, peuvent exister dans la base de données. La base de données peut utiliser des clichés de données à différents moments pour fournir des vues cohérentes en lecture des données et activer des interrogations non bloquantes.

La cohérence en lecture est garantie dans les environnements mono-instance et Oracle Real Application Clusters (Oracle RAC). Oracle RAC utilise un mécanisme de transfert de blocs cache-cache appelé mécanisme "Cache Fusion" pour transférer des images cohérentes en lecture de blocs de données d'une instance de base de données à une autre.

Voir aussi :

Cohérence de lecture : Exemple

Cet exemple illustre une requête qui utilise des données d'annulation pour assurer la cohérence en lecture au niveau instruction au niveau de l'isolement validé en lecture.

Figure 1 : Cohérence de lecture dans le niveau d'isolement de lecture validée

Description de l'image cncpt069.gif

Lorsque la base extrait des blocs de données pour le compte d'une interrogation, elle s'assure que les données de chaque bloc reflètent le contenu du bloc au début de l'interrogation. La base de données annule les modifications apportées au bloc si nécessaire pour reconstruire le bloc jusqu'au moment où la requête a commencé à être traitée.

La base de données utilise un mécanisme de commande interne appelé SCN pour garantir l'ordre des transactions. Lorsque l'instruction SELECT entre dans la phase d'exécution, la base de données détermine le numéro SCN enregistré au moment de l'exécution de la requête. Dans la Figure 12-1, ce numéro SCN est 10023. La requête voit uniquement les données validées par rapport au SCN 10023.

Dans la Figure 12-1, les blocs avec des numéros SCN après 10023 indiquent des données modifiées, comme le montrent les deux blocs avec le numéro SCN 10024. L'instruction SELECT requiert une version du bloc cohérente avec les modifications validées. La base de données copie les blocs de données en cours dans un nouveau tampon et applique les données d'annulation pour reconstruire les versions précédentes des blocs. Ces blocs de données reconstruits sont appelés clones de lecture cohérente (CR).

Dans la Figure 12-1, la base de données crée deux clones CR : un bloc cohérent avec le numéro SCN 10006 et l'autre bloc cohérent avec le numéro SCN 10021. La base de données renvoie les données reconstruites pour l'interrogation. De cette façon, Oracle AI Database empêche les lectures modifiées.

Voir aussi : "Database Buffer Cache" et "System Change Numbers (SCN)"

Lire les listes de cohérence et de transactions intéressées

L'en-tête de bloc de chaque bloc de segment contient une liste de transactions intéressées (ITL).

La base de données utilise l'ITL pour déterminer si une transaction n'a pas été validée lorsque la base de données a commencé à modifier le bloc.

Les entrées de l'ITL décrivent quelles transactions ont des lignes verrouillées et quelles lignes du bloc contiennent des modifications validées et non validées. L'ITL pointe vers la table des transactions du segment d'annulation, qui fournit des informations sur le moment auquel les modifications apportées à la base de données sont effectuées.

En un sens, l'en-tête du bloc contient un historique récent des transactions qui ont affecté chaque ligne du bloc. Le paramètre INITRANS des instructions CREATE TABLE et ALTER TABLE contrôle la quantité de l'historique des transactions conservée.

Voir aussi : Référence du langage SQL d'Oracle AI Database pour en savoir plus sur le paramètre INITRANS

Cohérence de lecture et insertions différées

Un type spécial d'insertion appelé insertion différée n'utilise pas le mécanisme de cohérence en lecture standard.

Une insertion différée utilise le conseil MEMOPTIMIZE_WRITE pour effectuer une insertion dans une table indiquée en tant que MEMOPTIMIZE FOR WRITE. Les tampons de la base de données insérés dans la zone de mémoire LARGE POOL plutôt que dans le cache de tampons. La base de données ne suit pas les modifications à l'aide des informations de journalisation et d'annulation. Au lieu de cela, la base de données valide automatiquement les modifications lorsque le coordinateur de la gestion de l'espace (SMCO) écrit le tampon sur le disque. Les modifications ne peuvent pas être annulées.

Les inserts différés diffèrent des inserts conventionnels de manière importante :

Les applications client qui doivent éviter la perte de données doivent conserver une copie locale des données après avoir écrit dans la zone de mémoire LARGE POOL. Le client peut utiliser le package DBMS_MEMOPTIMIZE pour suivre la durabilité des écritures dans la mémoire et le package DBMS_MEMOPTIMIZE_ADMIN pour forcer la base de données à écrire sur le disque.

Voir aussi :

Mécanismes de verrouillage

En général, les bases de données multiutilisateurs utilisent une certaine forme de verrouillage des données pour résoudre les problèmes liés à la simultanéité, à la cohérence et à l'intégrité des données.

Un verrou est un mécanisme qui empêche les interactions destructives entre les transactions qui accèdent à la même ressource.

Voir aussi : "Présentation du mécanisme de verrouillage d'Oracle AI Database"

Niveaux d'isolement des transactions ANSI/ISO

La norme SQL, qui a été adoptée par l'ANSI et ISO/IEC, définit quatre niveaux d'isolement des transactions. Ces niveaux ont différents degrés d'impact sur le débit de traitement des transactions.

Ces niveaux d'isolement sont définis en termes de phénomènes qui doivent être évités entre l'exécution simultanée de transactions. Les phénomènes évitables sont :

La norme SQL définit quatre niveaux d'isolement en termes de phénomènes qu'une transaction exécutée à un niveau d'isolement particulier est autorisée à expérimenter. Le Table 12-1 présente les niveaux.

Tableau 1 Phénomènes de lecture évitables par niveau d'isolement

Niveau d'isolement Lecture de données modifiées Lecture non répétable Lecture fantôme
Lecture non validée Possible Possible Possible
Lecture validée Impossible Possible Possible
Lecture reproductible Impossible Impossible Possible
Sérialisable Impossible Impossible Impossible

Oracle AI Database offre les niveaux d'isolement validé en lecture (par défaut) et sérialisable. En outre, la base de données offre un mode lecture seule.

Voir aussi :

Présentation des niveaux d'isolement des transactions Oracle AI Database

La norme ANSI pour les niveaux d'isolement des transactions est définie en termes de phénomènes qui sont autorisés ou empêchés pour chaque niveau d'isolement.

Oracle AI Database fournit les niveaux d'isolement des transactions :

Voir aussi :

Lire le niveau d'isolement validé

Dans le niveau d'isolement validé en lecture, chaque requête exécutée par une transaction ne voit que les données validées avant la requête, et non la transaction.

Ce niveau d'isolement est la valeur par défaut. Il convient aux environnements de base de données dans lesquels peu de transactions sont susceptibles d'être en conflit.

Une requête dans une transaction validée en lecture évite de lire les données qui sont validées pendant que la requête est en cours. Par exemple, si une requête est à mi-chemin d'un balayage d'une table de millions de lignes, et si une transaction différente valide une mise à jour vers la ligne 950 000, la requête ne voit pas cette modification lorsqu'elle lit la ligne 950 000. Toutefois, étant donné que la base de données n'empêche pas les autres transactions de modifier les données lues par une requête, d'autres transactions peuvent modifier les données entre les exécutions de requête. Par conséquent, une transaction qui exécute la même requête deux fois peut subir des lectures partielles et des fantômes.

Cohérence de lecture dans le niveau d'isolement de lecture validée

La base de données fournit un ensemble de résultats cohérent pour chaque requête, garantissant la cohérence des données, sans aucune action de l'utilisateur.

Une interrogation implicite, telle qu'une requête implicite par une clause WHERE dans une instruction UPDATE, est garantie d'un ensemble cohérent de résultats. Cependant, chaque instruction d'une interrogation implicite ne voit pas les modifications apportées par l'instruction LMD elle-même, mais voit les données telles qu'elles existaient avant que les modifications aient été effectuées.

Si une liste SELECT contient une fonction PL/SQL, la base de données applique la cohérence en lecture au niveau instruction pour l'exécution SQL dans le code de la fonction PL/SQL, plutôt qu'au niveau SQL parent. Par exemple, une fonction peut accéder à une table dont les données sont modifiées et validées par un autre utilisateur. Pour chaque exécution de SELECT dans la fonction, un nouvel instantané cohérent en lecture est établi.

Voir aussi : "Sous-requêtes"

Ecritures en conflit dans les transactions validées en lecture

Dans une transaction validée en lecture, une écriture en conflit se produit lorsque la transaction tente de modifier une ligne mise à jour par une transaction simultanée non validée.

La transaction qui empêche la modification de ligne est parfois appelée transaction bloquante. La transaction validée en lecture attend que la transaction bloquante se termine et libère son verrouillage de ligne.

Les options sont les suivantes :

Le tableau suivant montre comment la transaction 1, qui peut être sérialisable ou validée en lecture, interagit avec la transaction validée en lecture 2. Il présente une situation classique appelée mise à jour perdue. La mise à jour effectuée par la transaction 1 ne figure pas dans la table même si la transaction 1 l'a validée. La définition d'une stratégie de gestion des mises à jour perdues est un élément important du développement d'applications.

Tableau 2 Ecritures et mises à jour perdues en conflit dans une transaction READ COMMITTED

Session 1 Session 2 Explication
SQL> SELECT last_name,
  salary FROM employees
  WHERE last_name IN
  ('Banda', 'Greene',
 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 6200
 Greene 9500 
Aucune action La session 1 interroge les salaires de Banda, Greene et Hintz. Aucun employé nommé Hintz n'a été trouvé.
SQL> UPDATE employees
  SET salary = 7000 WHERE
  last_name = 'Banda';
Aucune action La session 1 commence une transaction en mettant à jour le salaire de Banda. Le niveau d'isolement par défaut de la transaction 1 est READ COMMITTED.
Aucune action
SQL> SET TRANSACTION
  ISOLATION LEVEL
  READ COMMITTED;
La session 2 commence la transaction 2 et définit explicitement le niveau d'isolement sur READ COMMITTED.
Aucune action
SQL> SELECT last_name,
  salary FROM employees
  WHERE last_name IN
 ('Banda', 'Greene',
 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 6200
 Greene 9500
La transaction 2 interroge les salaires de Banda, Greene et Hintz. Oracle AI Database utilise la cohérence en lecture pour afficher le salaire de Banda avant la mise à jour non validée effectuée par la transaction 1.
Aucune action
SQL> UPDATE employees
  SET salary = 9900
  WHERE last_name='Greene';
La transaction 2 met à jour le salaire de Greene avec succès car la transaction 1 a verrouillé uniquement la ligne Banda.
SQL> INSERT INTO
  employees (employee_id,
  last_name, email,
  hire_date, job_id)
  VALUES (210, 'Hintz',
  'JHINTZ', SYSDATE,
  'SH_CLERK');
Aucune action La transaction 1 insère une ligne pour l'employé Hintz, mais ne la valide pas.
Aucune action
SQL> SELECT last_name,
  salary FROM employees
  WHERE last_name IN
  ('Banda', 'Greene',
 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 6200
 Greene 9900

La transaction 2 interroge les salaires des employés Banda, Greene et Hintz.

La transaction 2 voit sa propre mise à jour du salaire de Greene. La transaction 2 ne voit pas la mise à jour non validée du salaire de Banda ni l'insertion de Hintz effectuée par la transaction 1.

Aucune action
SQL> UPDATE employees SET
 salary = 6300 WHERE
  last_name = 'Banda';

  -- prompt does not return 
La transaction 2 tente de mettre à jour la ligne pour Banda, qui est actuellement verrouillée par la transaction 1, créant ainsi une écriture conflictuelle. La transaction 2 attend la fin de la transaction 1.
SQL> COMMIT;
Aucune action La transaction 1 valide son travail et met fin à la transaction.
Aucune action
1 row updated.

  SQL>
Le verrou sur la ligne Banda est maintenant libéré, de sorte que la transaction 2 procède à sa mise à jour du salaire de Banda.
Aucune action
SQL> SELECT last_name,
  salary FROM employees
  WHERE last_name IN
 ('Banda', 'Greene',
  'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 6300
 Greene 9900
 Hintz
La transaction 2 interroge les salaires des employés Banda, Greene et Hintz. L'insertion Hintz validée par la transaction 1 est désormais visible par la transaction 2. La transaction 2 voit sa propre mise à jour du salaire de Banda.
Aucune action
COMMIT;
La transaction 2 valide son travail et met fin à la transaction.
SQL> SELECT last_name,
  salary FROM employees
  WHERE last_name IN
  ('Banda', 'Greene',
 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 6300
 Greene 9900
 Hintz
Aucune action La session 1 interroge les lignes de Banda, Greene et Hintz. Le salaire de Banda est de 6300, soit la mise à jour effectuée par la transaction 2. La mise à jour du salaire de Banda à 7000 effectuée par la transaction 1 est maintenant "perdue".

Voir aussi :

Niveau d'isolement sérialisable

Dans le niveau d'isolement sérialisable, une transaction ne voit que les modifications validées au moment où la transaction, et non la requête, a commencé et les modifications apportées par la transaction elle-même.

Une transaction sérialisable fonctionne dans un environnement qui la fait apparaître comme si aucun autre utilisateur ne modifiait les données de la base. L'isolation sérialisable convient aux environnements :

En isolement sérialisable, la cohérence de lecture normalement obtenue au niveau de l'instruction s'étend à l'ensemble de la transaction. Toute ligne lue par la transaction est assurée d'être la même lors de la relecture. Toute requête est garantie de renvoyer les mêmes résultats pendant toute la durée de la transaction. Par conséquent, les modifications apportées par d'autres transactions ne sont pas visibles par la requête, quelle que soit la durée de son exécution. Les transactions sérialisables ne connaissent pas de lectures modifiées, de lectures partielles ou de lectures fantômes.

Oracle AI Database permet à une transaction sérialisable de modifier une ligne uniquement si les modifications apportées à la ligne par d'autres transactions ont été déjà validées au début de la transaction sérialisable. La base de données génère une erreur lorsqu'une transaction sérialisable tente de mettre à jour ou de supprimer des données modifiées par une autre transaction qui a été validée après le début de la transaction sérialisable :

ORA-08177: Cannot serialize access for this transaction

Lorsqu'une transaction sérialisable échoue avec l'erreur ORA-08177, une application peut effectuer plusieurs actions, notamment :

Le tableau suivant montre comment une transaction sérialisable interagit avec d'autres transactions. Si la transaction sérialisable ne tente pas de modifier une ligne validée par une autre transaction après le début de la transaction sérialisable, un problème d'accès sérialisé est évité.

Tableau 3 - Transaction sérialisable

Session 1 Session 2 Explication
SQL> SELECT last_name, salary FROM employees WHERE
  last_name IN ('Banda',
  'Greene', 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 6200
 Greene 9500
Aucune action La session 1 interroge les salaires de Banda, Greene et Hintz. Aucun employé nommé Hintz n'a été trouvé.
SQL> UPDATE employees
  SET salary = 7000
  WHERE last_name='Banda';
Aucune action La session 1 commence la transaction 1 en mettant à jour le salaire de Banda. Le niveau d'isolement par défaut est READ COMMITTED.
Aucune action
SQL> SET TRANSACTION
  ISOLATION LEVEL SERIALIZABLE;
La session 2 commence la transaction 2 et la définit sur le niveau d'isolement SERIALIZABLE.
Aucune action
SQL> SELECT last_name, salary FROM employees
  WHERE last_name IN
  ('Banda', 'Greene', 'Hintz');

  LAST_NAME SALARY
 ------------ ----------
 Banda 6200
 Greene 9500
La transaction 2 interroge les salaires de Banda, Greene et Hintz. Oracle AI Database utilise la cohérence en lecture pour afficher le salaire de Banda avant la mise à jour non validée effectuée par la transaction 1.
Aucune action
SQL> UPDATE employees
  SET salary = 9900
  WHERE last_name = 'Greene';
La transaction 2 met à jour le salaire Greene avec succès car seule la ligne Banda est verrouillée.
SQL> INSERT INTO employees
  (employee_id, last_name,
  email, hire_date, job_id)
  VALUES (210, 'Hintz',
  'JHINTZ', SYSDATE,'SH_CLERK');
Aucune action La transaction 1 insère une ligne pour l'employé Hintz.
SQL> COMMIT;
Aucune action La transaction 1 valide son travail et met fin à la transaction.
SQL> SELECT last_name, salary
  FROM employees
  WHERE last_name IN
  ('Banda', 'Greene', 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 7000
 Greene 9500
 Hintz
SQL> SELECT last_name, salary FROM employees
  WHERE last_name IN
 ('Banda', 'Greene', 'Hintz');

  LAST_NAME SALARY
 ------------- ---------
 Banda 6200
 Greene 9900

La session 1 interroge les salaires des employés Banda, Greene et Hintz et voit les modifications validées par la transaction 1. La session 1 ne voit pas la mise à jour Greene non validée effectuée par la transaction 2.

La transaction 2 interroge les salaires des employés Banda, Greene et Hintz. La cohérence en lecture d'Oracle AI Database garantit que l'insertion Hintz et la mise à jour Banda validées par la transaction 1 ne sont pas visibles par la transaction 2. La transaction 2 voit sa propre mise à jour du salaire de Greene.

Aucune action
COMMIT;
La transaction 2 valide son travail et met fin à la transaction.
SQL> SELECT last_name, salary
  FROM employees
  WHERE last_name IN
  ('Banda', 'Greene', 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 7000
 Greene 9900
 Hintz
SQL> SELECT last_name, salary
 FROM employees
  WHERE last_name IN
  ('Banda', 'Greene', 'Hintz');

  LAST_NAME SALARY
 ------------- ---------
 Banda 7000
 Greene 9900
 Hintz
Les deux sessions interrogent les salaires de Banda, Greene et Hintz. Chaque session voit toutes les modifications validées effectuées par la transaction 1 et la transaction 2.
SQL> UPDATE employees
  SET salary = 7100
  WHERE last_name = 'Hintz';
Aucune action La session 1 commence la transaction 3 en mettant à jour le salaire Hintz. Le niveau d'isolement par défaut de la transaction 3 est READ COMMITTED.
Aucune action
SQL> SET TRANSACTION
  ISOLATION LEVEL SERIALIZABLE;
La session 2 commence la transaction 4 et la définit sur le niveau d'isolement SERIALIZABLE.
Aucune action
SQL> UPDATE employees
  SET salary = 7200
  WHERE last_name = 'Hintz';

  -- prompt does not return
La transaction 4 tente de mettre à jour le salaire pour Hintz, mais elle est bloquée car la transaction 3 a verrouillé la ligne Hintz. File d'attente de la transaction 4 derrière la transaction 3.
SQL> COMMIT;
Aucune action La transaction 3 valide sa mise à jour du salaire Hintz, mettant fin à la transaction.
Aucune action
UPDATE employees
  SET salary = 7200
  WHERE last_name = 'Hintz'
 *
 ERROR at line 1:
  ORA-08177: can't
  serialize access for
  this transaction
La validation qui met fin à la transaction 3 entraîne l'échec de la mise à jour Hintz dans la transaction 4 avec l'erreur ORA-08177. Le problème se produit car la transaction 3 a validé la mise à jour Hintz après le début de la transaction 4.
Aucune action
SQL> ROLLBACK;
La session 2 annule la transaction 4, qui met fin à la transaction.
Aucune action
SQL> SET TRANSACTION
  ISOLATION LEVEL SERIALIZABLE;
La session 2 commence la transaction 5 et la définit sur le niveau d'isolement SERIALIZABLE.
Aucune action
SQL> SELECT last_name,
  salary FROM employees
  WHERE last_name IN
  ('Banda', 'Greene', 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 7000
 Greene 9900
 Hintz 7100
La transaction 5 demande les salaires de Banda, Greene et Hintz. La mise à jour de salaire Hintz validée par la transaction 3 est visible.
Aucune action
SQL> UPDATE employees
  SET salary = 7200
  WHERE last_name='Hintz';

  1 row updated.

La transaction 5 met à jour le salaire Hintz avec une autre valeur. Etant donné que la mise à jour Hintz effectuée par la transaction 3 a été validée avant le début de la transaction 5, le problème d'accès sérialisé est évité.

Remarque : si une autre transaction a mis à jour et validé la ligne Hintz après le début de la transaction 5, le problème d'accès sérialisé se produit à nouveau.

Aucune action
SQL> COMMIT; 
La session 2 valide la mise à jour sans aucun problème, mettant fin à la transaction.

Voir aussi :

Niveau d'isolement en lecture seule

Le niveau d'isolement en lecture seule est similaire au niveau d'isolement sérialisable, mais les transactions en lecture seule ne permettent pas de modifier les données dans la transaction, sauf si l'utilisateur est SYS.

Les transactions en lecture seule ne sont pas sensibles à l'erreur ORA-08177. Les transactions en lecture seule sont utiles pour générer des rapports dans lesquels le contenu doit être cohérent par rapport à l'heure à laquelle la transaction a commencé.

Oracle AI Database assure la cohérence en lecture en reconstruisant les données selon les besoins à partir des segments d'annulation. Etant donné que les segments d'annulation sont utilisés de manière circulaire, la base de données peut écraser les données d'annulation. Les rapports à longue durée d'exécution risquent de réutiliser les données d'annulation requises pour la cohérence en lecture par une autre transaction, ce qui génère une erreur snapshot too old. La définition d'une période de conservation des annulations, qui correspond à la durée minimale pendant laquelle la base de données tente de conserver les anciennes données d'annulation avant de les écraser, permet d'éviter ce problème.

Voir aussi :

Présentation du mécanisme de verrouillage d'Oracle AI Database

Un verrou est un mécanisme qui empêche les interactions destructives.

Les interactions sont destructives lorsqu'elles mettent à jour les données de manière incorrecte ou modifient de manière incorrecte les structures de données sous-jacentes, entre les transactions accédant aux données partagées. Les verrous jouent un rôle crucial dans le maintien de la simultanéité et de la cohérence de la base de données.

Récapitulatif du comportement de verrouillage

La base de données gère plusieurs types de verrou, selon l'opération qui a acquis le verrou.

En général, la base de données utilise deux types de verrous : les verrous exclusifs et les verrous partagés. Un seul verrou exclusif peut être obtenu sur une ressource telle qu'une ligne ou une table, mais de nombreux verrous de partage peuvent être obtenus sur une seule ressource.

Les verrous affectent l'interaction des lecteurs et des rédacteurs. Un processus de lecture est une requête sur une ressource, tandis qu'un processus d'écriture est une instruction modifiant une ressource. Les règles suivantes récapitulent le comportement de verrouillage d'Oracle AI Database pour les lecteurs et les rédacteurs :

Voir aussi :

Utilisation des verrous

Dans une base de données mono-utilisateur, les verrous ne sont pas nécessaires car un seul utilisateur modifie les informations. Toutefois, lorsque plusieurs utilisateurs accèdent aux données et les modifient, la base de données doit fournir un moyen d'empêcher la modification simultanée des mêmes données.

Les verrous répondent aux exigences de base de données importantes suivantes :

Oracle AI Database fournit une simultanéité d'accès aux données, une cohérence et une intégrité entre les transactions via ses mécanismes de verrouillage. Le verrouillage se produit automatiquement et ne nécessite aucune action de l'utilisateur.

Le besoin de verrous peut être illustré par une mise à jour simultanée d'une seule ligne. Dans l'exemple suivant, une application Web simple présente à l'utilisateur final un courriel et un numéro de téléphone d'employé. L'application utilise une instruction UPDATE telle que la suivante pour modifier les données :

UPDATE employees
SET    email = ?, phone_number = ?
WHERE  employee_id = ?
AND    email = ?
AND    phone_number = ?

Dans l'instruction UPDATE précédente, les valeurs de courriel et de numéro de téléphone dans la clause WHERE sont les valeurs d'origine non modifiées pour l'employé indiqué. Cette mise à jour garantit que la ligne modifiée par l'application n'a pas été modifiée après la dernière lecture de l'application et qu'elle a été affichée à l'utilisateur. Ainsi, l'application évite le problème de mise à jour perdue dans lequel un utilisateur écrase les modifications apportées par un autre utilisateur, ce qui entraîne la perte de la mise à jour par le deuxième utilisateur (le Table 12-2 montre un exemple de mise à jour perdue). Le tableau 12-4 présente la séquence d'événements lorsque deux sessions tentent de modifier la même ligne dans la table employees à peu près au même moment.

Tableau 4 - Exemple de verrouillage de ligne

T Session 1 Session 2 Description
t0
SELECT employee_id as ID,
  email, phone_number
  FROM hr.employees
  WHERE last_name='Himuro';
ID EMAIL PHONE_NUMBER
 --- ------- ------------
 118 GHIMURO 515.127.4565
  Dans la session 1, l'utilisateur hr1 demande à hr.employees l'enregistrement Himuro et affiche les attributs employee_id (118), email (GHIMURO) et phone number (515.127.4565).
t1  
SELECT employee_id as ID,
 email, phone_number
  FROM hr.employees
  WHERE last_name='Himuro';
ID EMAIL PHONE_NUMBER
 --- ------- ------------
 118 GHIMURO 515.127.4565
Dans la session 2, l'utilisateur hr2 demande à hr.employees l'enregistrement Himuro et affiche les attributs employee_id (118), email (GHIMURO) et phone number (515.127.4565).
t2
UPDATE hr.employees SET
  phone_number='515.555.1234'
 WHERE employee_id=118
 AND email='GHIMURO'
 AND phone_number =
  '515.127.4565';

  1 row updated.
  Dans la session 1, l'utilisateur hr1 met à jour le numéro de téléphone de la ligne sur 515.555.1234, ce qui acquiert un verrou sur la ligne GHIMURO.
t3  
UPDATE hr.employees SET
  phone_number='515.555.1235'
 WHERE employee_id=118
 AND email='GHIMURO'
 AND phone_number =
  '515.127.4565';

  -- SQL*Plus does not show
 -- a row updated message or
 -- return the prompt.

Dans la session 2, l'utilisateur hr2 tente de mettre à jour la même ligne, mais il est bloqué car hr1 traite actuellement la ligne.

La tentative de mise à jour effectuée par hr2 se produit presque simultanément avec la mise à jour hr1.

t4
COMMIT;

  Commit complete.
 

Dans la session 1, l'utilisateur hr1 valide la transaction.

L'engagement rend le changement pour Himuro permanent et débloque la session 2, qui attendait.

t5  
0 rows updated.

Dans la session 2, l'utilisateur hr2 découvre que la ligne GHIMURO a été modifiée de manière à ne plus correspondre à son prédicat.

Comme les prédicats ne correspondent pas, la session 2 ne met à jour aucun enregistrement.

t6
UPDATE hr.employees SET
  phone_number='515.555.1235'
 WHERE employee_id=118
 AND email='GHIMURO' AND
  phone_number='515.555.1234';

  1 row updated.
  Dans la session 1, l'utilisateur hr1 se rend compte qu'il a mis à jour la ligne GHIMURO avec le mauvais numéro de téléphone. L'utilisateur démarre une nouvelle transaction et met à jour le numéro de téléphone de la ligne sur 515.555.1235, ce qui verrouille la ligne GHIMURO.
t7  
SELECT employee_id as ID,
  email, phone_number
  FROM hr.employees
  WHERE last_name='Himuro';
ID EMAIL PHONE_NUMBER
 --- ------- ------------
 118 GHIMURO 515.555.1234
Dans la session 2, l'utilisateur hr2 demande à hr.employees l'enregistrement Himuro. L'enregistrement affiche la mise à jour du numéro de téléphone validée par la session 1 à l'adresse t4. La cohérence en lecture d'Oracle AI Database garantit que la session 2 ne voit pas la modification non validée effectuée sur t6.
t8  
UPDATE hr.employees SET
  phone_number='515.555.1235
  WHERE employee_id=118
 AND email='GHIMURO'
 AND phone_number =
 '515.555.1234';

  -- SQL*Plus does not show
 -- a row updated message or
 -- return the prompt.
Dans la session 2, l'utilisateur hr2 tente de mettre à jour la même ligne, mais il est bloqué car hr1 traite actuellement la ligne.
t9
ROLLBACK;

  Rollback complete.
  Dans la session 1, l'utilisateur hr1 annule la transaction, ce qui la termine.
t10  
1 row updated.
Dans la session 2, la mise à jour du numéro de téléphone réussit car la mise à jour de la session 1 a été annulée. La ligne GHIMURO correspond à son prédicat, de sorte que la mise à jour réussit.
t11  
COMMIT;

  Commit complete.
La session 2 valide la mise à jour, mettant fin à la transaction.

Oracle AI Database obtient automatiquement les verrous nécessaires lors de l'exécution des instructions SQL. Par exemple, pour qu'une session puisse modifier des données, la session doit d'abord verrouiller les données. Le verrou donne à la session un contrôle exclusif sur les données afin qu'aucune autre transaction ne puisse modifier les données verrouillées tant que le verrou n'est pas libéré.

Les mécanismes de verrouillage d'Oracle AI Database étant étroitement liés au contrôle des transactions, les concepteurs d'applications doivent uniquement définir les transactions correctement et Oracle AI Database gère automatiquement le verrouillage. Les utilisateurs n'ont jamais besoin de verrouiller une ressource explicitement, bien qu'Oracle AI Database permette également aux utilisateurs de verrouiller les données manuellement.

Les sections suivantes expliquent les concepts importants pour comprendre comment Oracle AI Database atteint la simultanéité d'accès aux données.

Voir aussi : Référence des types et packages PL/SQL d'Oracle AI Database pour en savoir plus sur le package OWA_OPT_LOCK, qui contient des sous-programmes permettant d'éviter les mises à jour perdues

Modes de verrouillage

Oracle AI Database utilise automatiquement le plus bas niveau de restriction applicable pour fournir le plus haut degré de simultanéité des données tout en assurant l'intégrité des données de sécurité.

Moins le niveau est restrictif, plus les données sont disponibles pour l'accès d'autres utilisateurs. Inversement, plus le niveau est restrictif, plus les autres transactions sont limitées dans les types de verrous qu'elles peuvent acquérir.

Oracle AI Database utilise deux modes de verrouillage dans une base de données multiutilisateur :

Supposons qu'une transaction utilise une instruction SELECT ... FOR UPDATE pour sélectionner une seule ligne de table. La transaction acquiert un verrou de ligne exclusif et un verrou de table de partage de lignes. Le verrouillage de ligne permet aux autres sessions de modifier les lignes autres que la ligne verrouillée, tandis que le verrouillage de table empêche les sessions de modifier la structure de la table. Par conséquent, la base de données permet l'exécution d'autant d'instructions que possible.

Conversion de verrou et escalade

Oracle AI Database effectue la conversion de verrou si nécessaire.

Lors de la conversion d'un verrou, la base de données convertit automatiquement un verrou de table avec une restriction inférieure en un verrou avec une restriction supérieure. Par exemple, supposons qu'une transaction émet une valeur SELECT ... FOR UPDATE pour un employé et mette à jour ultérieurement la ligne verrouillée. Dans ce cas, la base de données convertit automatiquement le verrou de la table de partage de lignes en verrou de table exclusif de lignes. Une transaction contient des verrous de ligne exclusifs pour toutes les lignes insérées, mises à jour ou supprimées dans la transaction. Etant donné que les verrous de ligne sont acquis au degré de restriction le plus élevé, aucune conversion de verrou n'est requise ou effectuée.

La conversion des verrous est différente de l'escalade des verrous, qui se produit lorsque de nombreux verrous sont détenus à un niveau de granularité (par exemple, des lignes) et qu'une base de données élève les verrous à un niveau de granularité plus élevé (par exemple, une table). Si une session verrouille de nombreuses lignes dans une table, certaines bases de données escaladent automatiquement les verrous de ligne vers une seule table. Le nombre de verrous diminue, mais la restriction de ce qui est verrouillé augmente.

Oracle AI Database n'escalade jamais les verrous. L'escalade des verrous augmente considérablement la probabilité d'interblocages. Supposons qu'un système tente d'escalader les verrous pour le compte de la transaction 1, mais ne peut pas le faire en raison des verrous détenus par la transaction 2. Un interblocage est créé si la transaction 2 nécessite également une escalade de verrouillage des mêmes données avant de pouvoir continuer.

Durée de verrouillage

Oracle AI Database libère automatiquement un verrou lorsqu'un événement se produit afin que la transaction ne nécessite plus la ressource.

Généralement, la base de données contient les verrous acquis par les instructions d'une transaction pendant la durée de la transaction. Ces verrous empêchent les interférences destructives telles que les lectures modifiées, les mises à jour perdues et les instructions DDL destructives des transactions simultanées. Remarque : un verrou de table pris sur une table enfant en raison d'une clé étrangère non indexée est détenu pendant la durée de l'instruction, et non pour la transaction. En outre, le package DBMS_LOCK permet de libérer et d'allouer des verrous définis par l'utilisateur à volonté et même de les conserver au-delà des limites de transaction.

Oracle AI Database libère tous les verrous acquis par les instructions d'une transaction lorsqu'elle est validée ou annulée. Oracle AI Database libère également les verrous acquis après un point de sauvegarde lors de l'annulation vers le point de sauvegarde. Cependant, seules les transactions qui n'attendent pas les ressources précédemment verrouillées peuvent acquérir des verrous sur les ressources désormais disponibles. Les transactions en attente continuent d'attendre une validation ou une annulation complète de la transaction d'origine.

Voir aussi :

Verrous et interblocages

Un verrou mortel est une situation dans laquelle au moins deux utilisateurs attendent des données verrouillées l'un par l'autre. Les interblocages empêchent certaines transactions de continuer à fonctionner.

Oracle AI Database détecte automatiquement les interblocages et les résout en annulant une instruction impliquée dans l'interblocage, en libérant un ensemble de verrous de ligne en conflit. La base de données renvoie un message correspondant à la transaction qui fait l'objet d'une annulation au niveau instruction. L'instruction annulée (rollback) appartient à la transaction qui détecte le blocage. Généralement, la transaction signalée doit être annulée explicitement, mais elle peut réessayer l'instruction annulée après l'attente. Le Table 12-5 illustre deux transactions dans un interblocage.

Tableau 5 Transactions avec interblocage

T Session 1 Session 2 Explication
t0
SQL> UPDATE employees
  SET salary = salary*1.1
 WHERE employee_id = 100;

  1 row updated.
SQL> UPDATE employees
 SET salary = salary*1.1
 WHERE employee_id = 200;

  1 row updated.
La session 1 démarre la transaction 1 et met à jour le salaire de l'employé 100. La session 2 démarre la transaction 2 et met à jour le salaire de l'employé 200. Il n'existe aucun problème car chaque transaction verrouille uniquement la ligne qu'elle tente de mettre à jour.
t1
SQL> UPDATE employees
  SET salary = salary*1.1
 WHERE employee_id = 200;

  -- prompt does not return
SQL> UPDATE employees
 SET salary = salary*1.1
 WHERE employee_id = 100;

  -- prompt does not return

La transaction 1 tente de mettre à jour la ligne 200 du salarié, qui est actuellement verrouillée par la transaction 2. La transaction 2 tente de mettre à jour la ligne 100 du salarié, qui est actuellement verrouillée par la transaction 1.

Résultat d'un interblocage car aucune des transactions ne peut obtenir la ressource dont elle a besoin pour continuer ou s'interrompre. Quelle que soit la durée d'attente de chaque transaction, les verrous en conflit sont conservés.

t2
UPDATE employees
 *
 ERROR at line 1:
 ORA-00060: deadlock detected
 while waiting for resource

  SQL>
 

La transaction 1 signale le blocage et annule l'instruction UPDATE émise à l'adresse t1. Toutefois, la mise à jour effectuée sur t0 n'est pas annulée. L'invite est renvoyée dans la session 1.

Remarque : une seule session dans l'interblocage reçoit réellement l'erreur d'interblocage, mais l'une ou l'autre session peut obtenir l'erreur.

t3
SQL> COMMIT;

  Commit complete.
  La session 1 valide la mise à jour effectuée à l'adresse t0, mettant fin à la transaction 1. Echec de la tentative de mise à jour sur t1. La mise à jour n'est pas validée.
t4  
1 row updated.

  SQL>
La mise à jour à l'adresse t1 dans la transaction 2, qui était bloquée par la transaction 1, est exécutée. L'invite est renvoyée.
t5  
SQL> COMMIT;

  Commit complete.
La session 2 valide les mises à jour effectuées à l'adresse t0 et t1, ce qui met fin à la transaction 2.

Les interblocages surviennent le plus souvent lorsque les transactions remplacent explicitement le verrouillage par défaut d'Oracle AI Database. Etant donné qu'Oracle AI Database n'escalade pas les verrous et n'utilise pas de verrous de lecture pour les requêtes, mais utilise un verrouillage de niveau ligne (plutôt que de niveau page), les interblocages se produisent rarement.

Voir aussi :

Présentation des verrous automatiques

Oracle AI Database verrouille automatiquement une ressource pour le compte d'une transaction afin d'empêcher d'autres transactions d'effectuer quelque chose qui nécessite un accès exclusif à la même ressource.

La base de données acquiert automatiquement différents types de verrous à différents niveaux de restriction en fonction de la ressource et de l'opération en cours. Remarque : la base de données ne verrouille jamais les lignes lors d'opérations de lecture simples.

Les verrous Oracle AI Database sont divisés en catégories, comme indiqué dans le tableau suivant.

Tableau 6 Catégories de verrouillage

Verrouiller Description Pour en savoir plus
Verrous DML Protégez les données. Par exemple, les verrous de table verrouillent des tables entières, tandis que les verrous de ligne verrouillent des lignes sélectionnées. "Verrous LMD"
Verrous LDD Protéger la structure des objets de schéma, par exemple les définitions de dictionnaire des tables et des vues. "Verrous LDD"
Verrous système Protéger les structures de base de données internes telles que les fichiers de données. Les verrous internes, les mutex et les verrous internes sont entièrement automatiques. "Verrous système"

Verrous DML

Un verrou LMD, également appelé verrou de données, garantit l'intégrité des données auxquelles plusieurs utilisateurs accèdent simultanément.

Par exemple, un verrou DML empêche deux clients d'acheter la dernière copie d'un livre disponible auprès d'un libraire en ligne. Ils empêchent l'interférence destructrice d'opérations DML et DDL simultanées en conflit.

Les instructions LMD acquièrent automatiquement les types de verrou suivants :

Dans les sections suivantes, l'acronyme entre parenthèses après chaque type de mode de verrouillage ou de verrouillage est l'abréviation utilisée dans le moniteur des verrous d'Oracle Enterprise Manager (Enterprise Manager). Enterprise Manager peut afficher TM pour n'importe quel verrou de table, plutôt que d'indiquer le mode de verrouillage de table (tel que RS ou SRX).

Verrous de ligne (TX)

Un verrou de ligne, également appelé verrou TX, est un verrou sur une seule ligne de la table. Une transaction acquiert un verrou de ligne pour chaque ligne modifiée par une instruction INSERT, UPDATE, DELETE, MERGE ou SELECT ... FOR UPDATE. Le verrouillage de ligne existe jusqu'à ce que la transaction soit validée ou annulée.

Les verrous de ligne servent principalement de mécanisme de mise en file d'attente pour empêcher deux transactions de modifier la même ligne. La base de données verrouille toujours une ligne modifiée en mode exclusif afin que les autres transactions ne puissent pas modifier la ligne tant que la transaction contenant le verrouillage n'est pas validée ou annulée. Le verrouillage de ligne fournit le meilleur verrouillage de grain possible et offre ainsi la meilleure simultanéité et le meilleur débit possible.

Remarque : si une transaction se termine en raison de l'échec de l'instance de la base de données, la récupération au niveau bloc rend une ligne disponible avant la récupération de la totalité de la transaction.

Si une transaction obtient un verrou pour une ligne, elle acquiert également un verrou pour la table contenant la ligne. Le verrouillage de table empêche les opérations LDD conflictuelles qui remplaceraient les modifications de données dans une transaction en cours. La Figure 12-2 illustre une mise à jour de la troisième ligne d'un tableau. Oracle AI Database place automatiquement un verrou exclusif sur la ligne mise à jour et un verrou sous-exclusif sur la table.

Figure 2 : Verrous de ligne et de table

Description de l'image cncpt265.gif

Verrous de ligne et accès simultané

Ce scénario illustre comment Oracle AI Database utilise les verrous de ligne pour la simultanéité d'accès aux données.

Trois sessions interrogent simultanément les mêmes lignes. Les sessions 1 et 2 procèdent à des mises à jour non validées sur différentes lignes, tandis que la session 3 n'effectue aucune mise à jour. Chaque session voit ses propres mises à jour non validées, mais pas les mises à jour non validées des autres sessions.

Tableau 7 - Exemple d'accès simultané aux données

T Session 1 Session 2 Session 3 Explication
t0
SELECT employee_id,
 salary
 FROM employees
 WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 512
 101 600
SELECT employee_id,
 salary
  FROM employees
 WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 512
 101 600
SELECT employee_id,
  salary
  FROM employees
 WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 512
 101 600
Trois sessions différentes interrogent simultanément l'ID et le salaire des employés 100 et 101. Les résultats renvoyés par chaque requête sont identiques.
t1
UPDATE hr.employees
 SET salary =
  salary+100
 WHERE
  employee_id=100;
    La session 1 met à jour le salaire de l'employé 100, mais ne s'engage pas. Dans la mise à jour, le processus d'écriture acquiert un verrou de niveau ligne pour la ligne mise à jour uniquement, ce qui empêche les autres processus d'écriture de modifier cette ligne.
t2
SELECT employee_id,
 salary
  FROM employees
  WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 612
 101 600
SELECT employee_id,
 salary
 FROM employees
 WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 512
 101 600
SELECT employee_id,
  salary
  FROM employees
 WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 512
 101 600
Chaque session émet simultanément la requête d'origine. La session 1 indique le salaire de 612 résultant de la mise à jour t1. Les processus de lecture des sessions 2 et 3 renvoient immédiatement des lignes et n'attendent pas que la session 1 termine sa transaction. La base de données utilise la cohérence en lecture multiversion pour afficher le salaire tel qu'il existait avant la mise à jour dans la session 1.
t3  
UPDATE hr.employee
 SET salary =
 salary+100
 WHERE
  employee_id=101;
  La session 2 met à jour le salaire de l'employé 101, mais ne valide pas la transaction. Dans la mise à jour, le processus d'écriture acquiert un verrou de niveau ligne pour la ligne mise à jour uniquement, ce qui empêche les autres processus d'écriture de modifier cette ligne.
t4
SELECT employee_id,
 salary
  FROM employees
  WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 612
 101 600
SELECT employee_id,
 salary
 FROM employees
  WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 512
 101 700
SELECT employee_id,
  salary
  FROM employees
 WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 512
 101 600
Chaque session émet simultanément la requête d'origine. La session 1 indique le salaire de 612 résultant de la mise à jour t1, mais pas la mise à jour du salaire de l'employé 101 effectuée dans la session 2. Le lecteur de la session 2 affiche la mise à jour de salaire effectuée dans la session 2, mais pas la mise à jour de salaire effectuée dans la session 1. Le lecteur de la session 3 utilise la cohérence en lecture pour afficher les salaires avant modification par session 1 et 2.

Voir aussi :

Stockage des verrous de ligne

Contrairement à certaines bases de données, qui utilisent un gestionnaire de verrous pour tenir à jour une liste de verrous en mémoire, Oracle AI Database stocke les informations de verrou dans le bloc de données qui contient la ligne verrouillée.

La base de données utilise un mécanisme de mise en file d'attente pour l'acquisition de verrous de ligne. Si une transaction nécessite un verrou pour une ligne déverrouillée, la transaction place un verrou dans le bloc de données. Chaque ligne modifiée par cette transaction pointe vers une copie de l'ID de transaction stocké dans l'en-tête de bloc.

Lorsqu'une transaction se termine, l'ID de transaction reste dans l'en-tête du bloc. Si une autre transaction souhaite modifier une ligne, elle utilise le code transaction pour déterminer si le verrou est actif. Si le verrou est actif, la session demande à être informée lorsque le verrou est libéré. Sinon, la transaction acquiert le verrou.

Voir aussi :

Verrous de table (TM)

Un verrou de table, également appelé verrou TM, est acquis par une transaction lorsqu'une table est modifiée par une instruction INSERT, UPDATE, DELETE, MERGE, SELECT avec la clause FOR UPDATE ou LOCK TABLE.

Les opérations LMD nécessitent des verrous internes (locks) sur les tables pour réserver l'accès LMD à la table pour le compte d'une transaction et pour empêcher les opérations LDD qui entreraient en conflit avec la transaction.

Un verrou de table peut être maintenu dans l'un des modes suivants :

Voir aussi :

Verrous et clés étrangères

Oracle AI Database optimise le contrôle de simultanéité des clés parent par rapport aux clés étrangères dépendantes.

Le comportement de verrouillage dépend de l'indexation des colonnes de clé étrangère. Si les clés étrangères ne sont pas indexées, la table enfant sera probablement verrouillée plus fréquemment, des interblocages se produiront et la simultanéité sera réduite. Pour cette raison, les clés étrangères doivent presque toujours être indexées. La seule exception est lorsque la clé unique ou primaire correspondante n'est jamais mise à jour ou supprimée.

Verrous et clés étrangères non indexées

La base de données acquiert un verrou complet sur la table enfant lorsqu'aucun index n'existe sur la colonne de clé étrangère de la table enfant et qu'une session modifie une clé primaire dans la table parent (par exemple, supprime une ligne ou modifie des attributs de clé primaire) ou fusionne des lignes dans la table parent.

Lorsque les deux conditions suivantes sont remplies, la base de données acquiert un verrou complet sur la table enfant :

Supposons que la table hr.departments soit un parent de hr.employees, qui contient la clé étrangère non indexée employees.department_id. La figure suivante illustre une session modifiant les attributs de clé primaire du département 60 dans la table departments.

Figure 3 : Mécanismes de verrouillage avec clé étrangère non indexée

Description de l'image cncpt308.gif

Dans la figure 12-3, la base de données acquiert un verrou de table complet sur employees lors de la modification de la clé primaire du département 60. Ce verrou permet aux autres sessions d'interroger la table employees, mais pas de la mettre à jour. Par exemple, les sessions ne peuvent pas mettre à jour les numéros de téléphone des employés. Le verrou de table sur employees est libéré immédiatement après la modification de la clé primaire sur la table departments. Si plusieurs lignes dans departments subissent des modifications de clé primaire, un verrou de table sur employees est obtenu et libéré une fois pour chaque ligne modifiée dans departments. Remarque : les instructions LMD sur une table enfant n'acquièrent pas de verrou sur la table parent.

Verrous et clés étrangères indexées

La base de données n'acquiert pas de verrou complet sur la table enfant lorsqu'une colonne de clé étrangère dans la table enfant est indexée et qu'une session modifie une clé primaire dans la table parent (par exemple, supprime une ligne ou modifie des attributs de clé primaire) ou fusionne des lignes dans la table parent.

Un verrou sur la table parent empêche les transactions d'acquérir des verrous de table exclusifs, mais n'empêche pas les opérations LMD sur la table parent ou enfant lors de la modification de la clé primaire. Cette situation est préférable si des modifications de clé primaire sont apportées à la table parent alors que des mises à jour sont effectuées sur la table enfant. La figure 12-4 présente la table enfant employees avec une colonne department_id indexée. Une transaction supprime le service 280 de departments. Cette suppression n'entraîne pas l'acquisition par la base de données d'un verrou de table complet sur la table employees, comme dans le scénario décrit dans la section "Verrous et clés étrangères non indexées".

Figure 4 : Mécanismes de verrouillage avec clé étrangère indexée

Description de l'image cncpt309.gif

Si la table enfant indique ON DELETE CASCADE, les suppressions de la table parent peuvent entraîner des suppressions de la table enfant. Par exemple, la suppression du service 280 peut entraîner la suppression d'enregistrements de employees pour les employés du service supprimé. Dans ce cas, les règles d'attente et de verrouillage sont les mêmes que si vous avez supprimé des lignes de la table enfant après avoir supprimé des lignes de la table parent.

Voir aussi :

Verrous LDD

Un verrou de dictionnaire de données (DDL) protège la définition d'un objet de schéma pendant qu'une opération LDD en cours agit sur l'objet ou y fait référence.

Seuls les objets de schéma individuels modifiés ou référencés sont verrouillés pendant les opérations LDD. La base ne verrouille jamais l'ensemble du dictionnaire de données.

Oracle AI Database acquiert automatiquement un verrou DDL pour le compte de toute transaction DDL qui en a besoin. Les utilisateurs ne peuvent pas demander explicitement des verrous LDD. Par exemple, si un utilisateur crée une procédure stockée, Oracle AI Database acquiert automatiquement des verrous LDD pour tous les objets de schéma référencés dans la définition de la procédure. Les verrous LDD empêchent la modification ou la suppression de ces objets avant la fin de la compilation des procédures.

Verrous LDD exclusifs

Un verrou LDD exclusif empêche les autres sessions d'obtenir un verrou LDD ou LMD.

La plupart des opérations LDD nécessitent des verrous LDD exclusifs pour une ressource afin d'éviter toute interférence destructive avec d'autres opérations LDD susceptibles de modifier ou de référencer le même objet de schéma. Par exemple, DROP TABLE n'est pas autorisé à supprimer une table lorsque ALTER TABLE y ajoute une colonne, et inversement.

Les verrous LDD exclusifs durent toute la durée de l'exécution des instructions LDD et de la validation automatique. Lors de l'acquisition d'un verrou LDD exclusif, si un autre verrou LDD est détenu sur l'objet de schéma par une autre opération, l'acquisition attend que l'ancien verrou LDD soit libéré, puis continue.

Voir aussi : "Partager les verrous DDL" décrit les situations dans lesquelles des verrous exclusifs ne sont pas nécessaires pour empêcher les interférences destructives.

Partager des verrous LDD

Un verrou LDD partagé pour une ressource empêche les interférences destructives avec les opérations LDD en conflit, mais autorise la simultanéité d'accès aux données pour des opérations LDD similaires.

Par exemple, lorsqu'une instruction CREATE PROCEDURE est exécutée, la transaction qui la contient acquiert des verrous LDD partagés pour toutes les tables référencées. D'autres transactions peuvent créer simultanément des procédures qui référencent les mêmes tables et acquièrent simultanément des verrous LDD partagés sur les mêmes tables, mais aucune transaction ne peut acquérir un verrou LDD exclusif sur une table référencée.

Un verrou LDD partagé dure pendant toute la durée de l'exécution et de la validation automatiques des instructions LDD. Ainsi, une transaction détenant un verrou LDD partagé est garantie que la définition de l'objet de schéma référencé reste constante pendant la transaction.

Verrous d'analyse cassables

Un verrou d'analyse est détenu par une instruction SQL ou une unité de programme PL/SQL pour chaque objet de schéma auquel il fait référence.

Les verrous d'analyse sont acquis afin que la zone SQL partagée associée puisse être invalidée si un objet référencé est modifié ou supprimé. Un verrou d'analyse est appelé verrou d'analyse pouvant faire l'objet d'une interruption car il n'interdit aucune opération LDD et peut être rompu pour autoriser les opérations LDD en conflit.

Un verrou d'analyse est acquis dans le pool partagé pendant la phase d'analyse de l'exécution de l'instruction SQL. Le verrou est conservé tant que la zone SQL partagée de cette instruction reste dans la zone de mémoire partagée.

Voir aussi : "Pool partagé"

Verrous système

Oracle AI Database utilise différents types de verrous système pour protéger les structures de base de données et de mémoire internes. Ces mécanismes sont inaccessibles aux utilisateurs car ils n'ont aucun contrôle sur leur occurrence ou leur durée.

Verrous internes

Un verrou est un mécanisme de sérialisation simple de bas niveau qui coordonne l'accès multiutilisateur aux structures de données, aux objets et aux fichiers partagés.

Les verrous internes protègent les ressources de mémoire partagée contre l'altération lorsque plusieurs processus y accèdent. Plus précisément, les verrous internes protègent les structures de données des situations suivantes :

En général, un verrou interne unique protège plusieurs objets de la mémoire SGA. Par exemple, les processus en arrière-plan tels que DBW et LGWR allouent de la mémoire à partir du pool partagé pour créer des structures de données. Pour allouer cette mémoire, ces processus utilisent un verrou interne de la zone de mémoire partagée qui sérialise l'accès pour empêcher deux processus d'essayer d'inspecter ou de modifier la zone de mémoire partagée simultanément. Une fois la mémoire allouée, d'autres processus peuvent avoir besoin d'accéder aux zones de la zone de mémoire partagée, telles que le cache de bibliothèque, qui est requis pour l'analyse. Dans ce cas, les processus verrouillent uniquement le cache de bibliothèque, et non l'ensemble de la zone de mémoire partagée.

Contrairement aux verrous de mise en file d'attente tels que les verrous de ligne, les verrous de mise en file d'attente n'autorisent pas les sessions à mettre en file d'attente. Lorsqu'un verrou est disponible, la première session à demander le verrou obtient un accès exclusif à celui-ci. Le phénomène de latch spinning se produit lorsqu'un processus demande à plusieurs reprises un verrou interne dans une boucle, tandis que latch sleep se produit lorsqu'un processus libère la CPU avant de renouveler la demande de verrou interne.

En règle générale, un processus Oracle acquiert un verrou interne pendant un temps extrêmement court tout en manipulant ou en examinant une structure de données. Par exemple, lors du traitement d'une mise à jour de salaire d'un seul employé, la base de données peut obtenir et libérer des milliers de verrous internes. L'implémentation des verrous dépend du système d'exploitation, en particulier pour ce qui est de savoir si et combien de temps un processus attend un verrou.

Une augmentation du verrouillage signifie une diminution de la simultanéité. Par exemple, un nombre excessif d'opérations d'analyse complète crée des contentions pour le verrou interne du cache "library". La vue V$LATCH contient des statistiques détaillées sur l'utilisation des verrous internes pour chaque verrou interne, y compris le nombre de fois où chaque verrou interne a été demandé et attendu.

Voir aussi :

Mutex

Un objet d'exclusion mutuelle (mutex) est un mécanisme de bas niveau qui empêche un objet de la mémoire de vieillir ou d'être endommagé lorsqu'il est consulté par des processus simultanés. Un mutex est similaire à un verrou, mais alors qu'un verrou protège généralement un groupe d'objets, un mutex protège un seul objet.

Les mutex offrent plusieurs avantages :

Verrous internes

Les verrous internes sont des mécanismes plus complexes et de plus haut niveau que les verrous internes et les mutex et servent à diverses fins.

La base de données utilise les types de verrous internes suivants :

Voir aussi : "Cache du dictionnaire de données"

Présentation des verrous de données manuels

Vous pouvez remplacer manuellement les mécanismes de verrouillage par défaut d'Oracle AI Database.

Oracle AI Database effectue le verrouillage automatiquement pour garantir la simultanéité d'accès aux données, l'intégrité des données et la cohérence en lecture au niveau des instructions. Toutefois, le remplacement du verrouillage par défaut est utile dans les situations suivantes :

Vous pouvez remplacer le verrouillage automatique d'Oracle AI Database au niveau de la session ou de la transaction. Au niveau de la session, une session peut définir le niveau d'isolement de transaction requis avec l'instruction ALTER SESSION. Au niveau transaction, les transactions qui incluent les instructions SQL suivantes remplacent le verrouillage par défaut d'Oracle AI Database :

Les verrous acquis par les instructions précédentes sont libérés une fois la transaction terminée ou une annulation (rollback) pour le point de sauvegarde les libère.

Si le verrouillage par défaut d'Oracle AI Database est remplacé à n'importe quel niveau, l'administrateur de base de données ou le développeur d'applications doit s'assurer que les procédures de verrouillage de remplacement fonctionnent correctement. Les procédures de verrouillage doivent satisfaire aux critères suivants : l'intégrité des données est garantie, la simultanéité d'accès aux données est acceptable et les interblocages ne sont pas possibles ou sont correctement gérés.

Voir aussi :

Présentation des verrous définis par l'utilisateur

Avec les services Oracle AI Database Lock Management, vous pouvez définir vos propres verrous pour une application spécifique.

Par exemple, vous pouvez créer un verrou pour sérialiser l'accès à un journal de messages sur le système de fichiers. Etant donné qu'un verrou utilisateur réservé est identique à un verrou Oracle AI Database, il dispose de toutes les fonctionnalités de verrouillage d'Oracle AI Database, y compris la détection des interblocages. Les verrous utilisateur n'entrent jamais en conflit avec les verrous Oracle AI Database, car ils sont identifiés par le préfixe UL.

Les services Oracle AI Database Lock Management sont disponibles via les procédures du package DBMS_LOCK. Vous pouvez inclure des instructions dans des blocs PL/SQL qui :

Voir aussi :


Note

Note 1 :

Lors du traitement d'une validation distribuée en deux phases, la base de données peut empêcher brièvement l'accès en lecture dans des circonstances particulières. Plus précisément, si une requête démarre entre les phases de préparation et de validation et tente de lire les données avant la validation, la base de données peut escalader un verrou de niveau ligne à niveau bloc pour garantir la cohérence en lecture.