Contrôle d'accès concurrentiel basé sur le verrouillage
L'utilisation du verrouillage pour contrôler l'accès aux ressources partagées est sujette à des blocages, et le planificateur de transactions seul ne peut pas empêcher leur occurrence.
Par exemple, les systèmes de bases de données relationnelles utilisent divers verrous pour garantir les propriétés ACID des transactions .
Quel que soit le système de base de données relationnelle que vous utilisez, les verrous seront toujours acquis lors de la modification (par exemple, UPDATE
ou DELETE
) d'un certain enregistrement de table. Sans verrouiller une ligne qui a été modifiée par une transaction en cours d'exécution, Atomicity serait compromis .
Qu'est-ce qu'une impasse
Comme je l'ai expliqué dans cet article , un blocage se produit lorsque deux transactions simultanées ne peuvent pas progresser car chacune attend que l'autre libère un verrou, comme illustré dans le diagramme suivant.
Étant donné que les deux transactions sont en phase d'acquisition de verrouillage, aucune des deux ne libère de verrou avant d'acquérir la suivante.
Se remettre d'une situation de blocage
Si vous utilisez un algorithme de contrôle d'accès concurrentiel qui repose sur des verrous, il existe toujours un risque de s'exécuter dans une situation de blocage. Des blocages peuvent se produire dans n'importe quel environnement de concurrence, pas seulement dans un système de base de données.
Par exemple, un programme multithreading peut se bloquer si deux ou plusieurs threads attendent des verrous qui ont été précédemment acquis afin qu'aucun thread ne puisse progresser. Si cela se produit dans une application Java, la JVM ne peut pas simplement forcer un Thread à arrêter son exécution et à libérer ses verrous.
Même si la Thread
classe expose une stop
méthode, cette méthode est obsolète depuis Java 1.1 car elle peut laisser les objets dans un état incohérent après l'arrêt d'un thread. Au lieu de cela, Java définit une interrupt
méthode, qui agit comme un indice car un thread qui est interrompu peut simplement ignorer l'interruption et continuer son exécution.
Pour cette raison, une application Java ne peut pas se remettre d'une situation de blocage, et il est de la responsabilité du développeur de l'application d'ordonner les demandes d'acquisition de verrou de manière à ce que les blocages ne puissent jamais se produire.
Cependant, un système de base de données ne peut pas appliquer un ordre d'acquisition de verrou donné car il est impossible de prévoir quels autres verrous une transaction donnée voudra acquérir davantage. La préservation de l'ordre de verrouillage devient la responsabilité de la couche d'accès aux données, et la base de données ne peut que faciliter la récupération après une situation de blocage.
Le moteur de base de données exécute un processus distinct qui analyse le graphique de conflit actuel pour les cycles d'attente de verrouillage (qui sont causés par des blocages). Lorsqu'un cycle est détecté, le moteur de base de données sélectionne une transaction et l'abandonne, provoquant la libération de ses verrous, afin que l'autre transaction puisse progresser.
Contrairement à la JVM, une transaction de base de données est conçue comme une unité de travail atomique. Par conséquent, une restauration laisse la base de données dans un état cohérent.
Pour plus de détails sur ce sujet, consultez également cet article .