Quelle est la relation exacte entre une transaction de base de données et le verrouillage?

16

Il s'agit d'une humble question posée dans l'esprit d'accroître mes connaissances; veuillez être gentil dans votre réponse.

En tant que développeur d'applications de longue date, je sais à un certain niveau ce qu'est une transaction (je les utilise tout le temps). En laissant de côté les niveaux d'isolement des transactions pour le moment, à un niveau élevé, une transaction permet de terminer un bloc de travail entièrement ou pas du tout, et permet une certaine isolation des autres activités de modification de la base de données.

Je sais également ce qu'est un verrou (dans diverses bases de données), ou du moins comment on se comporte (si je verrouille explicitement une table, aucun autre processus ou thread ne peut mettre à jour quoi que ce soit à propos de cette table).

Ce que je ne sais pas le plus clairement, c'est: dans diverses bases de données, lorsque je verrouille explicitement une ligne ou une table, est-ce que j'utilise exactement les mêmes constructions que celles utilisées par les fonctionnalités de transaction de la base de données sous les couvertures pour que la transaction fonctionne correctement?

Autrement dit, il me semble que pour qu'une transaction soit atomique et isolée, elle doit faire un certain verrouillage. Ce verrouillage initié par transaction et masqué par la tranaction est-il le même type de verrouillage auquel diverses bases de données me permettent d'accéder via des constructions telles que SELECT FOR UPDATEdes LOCKcommandes explicites ? Ou ces deux concepts sont-ils complètement différents?

Encore une fois, je m'excuse pour la naïveté de cette question; Je suis heureux d'être désigné par des sources plus fondamentales.

Laird Nelson
la source

Réponses:

12

Lorsque je verrouille explicitement une ligne ou une table, est-ce que j'utilise exactement les mêmes constructions que celles utilisées par les fonctionnalités de transaction de la base de données sous les couvertures pour que la transaction fonctionne correctement?

Oui. Si ce n'était pas le cas, votre propre «verrouillage» ne serait étendu qu'à un autre «verrouillage» similaire et n'interagirait pas avec le verrouillage du moteur. Ainsi, vous verrouilleriez une ligne dans une table afin qu'elle ne puisse pas être verrouillée par une autre application de la même manière, mais votre verrou serait ignoré par le moteur lui-même. Cette sémantique est rarement souhaitée. La plupart du temps, une application verrouillant une ligne signifie «la verrouiller contre tout moyen d'accès / modification». Side note que les mécanismes de verrouillage qui sont strictement spécifiques d'application n'existe, parce qu'ils sont utiles. Par exemple, SQL Server a des verrous d'application .

il me vient à l'esprit que pour qu'une transaction soit atomique et isolée, elle doit faire un certain verrouillage.

Le verrouillage est un moyen d'y parvenir. L'alternative majeure est le versioning. De nos jours, la plupart des bases de données prennent en charge les deux (ce qui signifie également que si vous `` verrouillez '' une ligne dans l'application mais qu'une autre transaction utilise la gestion des versions pour lire la ligne, elle la lira car votre verrouillage ne bloque pas les lectures versionnées).

Vous tournez en quelque sorte autour d'un concept connu dans le monde de la mise en œuvre de la base de données comme «protocole de verrouillage en deux phases» . l'article Wikipedia lié est une bonne entrée. Si vous souhaitez lire des explications plus détaillées sur ce sujet, je vous recommande de vous rendre à la bibliothèque et de demander un prêt sur Transaction Processing: Concepts and Techniques . Presque toutes les bases de données existent, à la base, une implémentation de ce livre.

Remus Rusanu
la source
Vous pouvez peut-être ajouter des informations sur le contrôle de concurrence optimiste
ypercubeᵀᴹ
Ah! Nous parlons maintenant. En effet, à l'arrière de mon esprit se cachait MVCC . Merci pour la réponse bien articulée, les excellentes références et pour avoir pris le temps de vraiment creuser ma question.
Laird Nelson
3

Quelques informations avant de répondre à vos questions:

Remarque: Ceci est lié à Microsoft SQL Server - RDBMS ........

  • En termes très simples, une transaction est une séquence de travaux qui doit être effectuée comme une seule unité logique dans son intégralité et doit conserver les propriétés ACID.
  • Tout SGBDR doit fournir des «installations de verrouillage» qui peuvent être utilisées pour terminer la transaction dans son intégralité, en préservant l'isolement de la transaction et sa durabilité. Cela garantit l'intégrité physique de la base de données.
  • Plus important encore, par défaut - les transactions sont gérées au niveau de la connexion. Ainsi, lorsqu'une transaction est démarrée sur une connexion, toutes les instructions T-SQL (S / I / U / D) exécutées sur cette connexion font partie de la transaction jusqu'à la fin de la transaction. ( MARS est géré différemment)

Revenons maintenant à vos questions:

Lorsque je verrouille explicitement une ligne ou une table, est-ce que j'utilise exactement les mêmes constructions que celles utilisées par les fonctionnalités de transaction de la base de données sous les couvertures pour que la transaction fonctionne correctement?

Oui. Cela signifie que vous devez être prudent dans la détermination de la séquence de données qui sera modifiée et qui laissera la base de données dans un état cohérent. En d'autres termes, votre opération DML doit laisser la base de données dans un état cohérent qui limite les règles métier de votre organisation. Pourtant, le SGBDR (ici SQL Server) peut appliquer l'intégrité physique de la transaction.

Depuis BOL: le verrouillage et le versionnage des lignes empêchent les utilisateurs de lire les données non validées et empêchent plusieurs utilisateurs d'essayer de modifier les mêmes données en même temps. Sans verrouillage ou versionnage de lignes, les requêtes exécutées sur ces données peuvent produire des résultats inattendus en renvoyant des données qui n'ont pas encore été validées dans la base de données.

Ce verrouillage initié par transaction et caché par transaction est-il le même type de verrouillage auquel diverses bases de données me permettent d'accéder via des constructions telles que SELECT FOR UPDATE ou des commandes LOCK explicites?

Tout dans SQL Server est contenu dans une transaction. Lorsque vous accédez à vos données, le SGBDR doit prendre des verrous en fonction du niveau d'isolement et des opérations que vous effectuez sur vos données. Vérifiez cette réponse pour plus de détails.

Quelques bonnes références:

Kin Shah
la source
2

Je dirais que les transactions font partie de l '"interface" de la base de données, dans un sens, c'est en tant que développeur que vous décidez quand commencer, terminer, quoi faire dans le cadre des transactions, etc. Les verrous, selon moi, appartiennent aux détails de l'implémentation et utilisé pour la synchronisation d'accès à différents objets. Dans la plupart des cas, le moteur décide lui-même de la durée et de la durée du verrouillage. Il existe de nombreux verrous au niveau du système qui ne peuvent pas être manipulés directement (par exemple, le moteur peut verrouiller certaines zones de mémoire). Même en ce qui concerne les verrous DML, beaucoup d'entre eux se produisent en arrière-plan (par exemple, pour garantir l'intégrité référentielle Oracle et, pour autant que je m'en souvienne, SQLServer peut mettre un verrou sur une ligne correspondante dans la table principale si un nouvel enregistrement est inséré dans détails) à la suite des instructions DML émises dans le cadre de la transaction.

En ce qui concerne les transactions, vous pouvez vous attendre à un comportement plus ou moins cohérent de tout RDMS qui prétend se conformer à SQL et prendre en charge les transactions, mais en ce qui concerne les verrous, presque tous les fournisseurs utilisent une stratégie et une terminologie différentes. Pour autant que je sache, la partie commune à tous les RMDS est que la concurrence entre les transactions est définie par le niveau d'isolement tandis que la concurrence entre les verrous est contrôlée par les types de verrous (partagés, exclusifs, etc.).

Pour résumer, les verrous sont un mécanisme de bas niveau pour contrôler la cohérence des objets et la concurrence. Des verrous peuvent être émis lors de l'exécution des instructions SQL. En fonction de l'implémentation du niveau d'isolation des transactions, le moteur peut placer différents types de verrous sur les objets affectés (lignes, groupe de lignes, index, etc.). Il existe un nombre limité de commandes disponibles pour émettre manuellement des verrous ( SELECT FOR UPDATE, LOCK). Les verrous DML peuvent être escaladés (dépend du RDMS, par exemple, dans la ligne SQLServer-> page-> partition-> table). Des verrous peuvent également être émis par le moteur de base de données pendant l'initiation de la connexion, les sauvegardes, la restauration, la recompilation de procédure / déclencheur / fonction / etc., le démarrage, les arrêts, etc.

Je ne sais pas si cela répond à votre question, mais j'espère que cela a du sens.

a1ex07
la source
Merci pour votre commentaire. Vous êtes certainement le plus proche jusqu'à présent. J'essaie toujours de voir si les transactions sont toujours implémentées en termes de verrous utilisés par, disons, explicites LOCKou des SELECT FOR UPDATEinstructions, ou via un autre mécanisme.
Laird Nelson
Pour autant que je sache, BEGIN TRANSACTIONlui - même n'émet aucun verrou. Des verrous apparaîtront après les DML dans la transaction.
a1ex07
Clarification - je voulais dire que BEGIN TRANSACTIONlui-même ne crée pas de verrous DML; il devrait en fait émettre des verrous internes car il doit allouer des ressources, ajouter une entrée à la ou aux tables système (le cas échéant) qui contient les transactions actives, etc.
a1ex07
1

J'utiliserai le jargon de SQL Server, mais les concepts devraient être les mêmes pour les autres fournisseurs:

Chaque commande que vous exécutez est exécutée dans une transaction. Cette transaction peut être ouverte explicitement avec BEGIN TRAN, ou implicitement, par le moteur de base de données. La raison pour laquelle une transaction implicite est ouverte est que le moteur doit toujours maintenir la conformité ACID et la possibilité d'un retour en arrière.

Lorsque vous effectuez un SELECT FOR UPDATE, cela signifie simplement que pendant que la transaction est en place, elle tiendra un certain verrou.

Matan Yungman
la source
Merci pour votre commentaire. Ça, je le sais. Mais ma question est toujours: lorsque cette transaction est ouverte, son isolement est-il accompli en tenant ses propres serrures? Si oui, ces verrous sont-ils les mêmes types de verrous que je peux acquérir explicitement? Ou la transaction atteint-elle l'isolement par d'autres moyens?
Laird Nelson
2
Oui, c'est le même mécanisme. L'isolement est obtenu en utilisant des verrous dans les deux modes, les mêmes verrous que vous pouvez acquérir explicitement. La différence est que si vous n'ouvrez pas explicitement une transaction, les verrous seront libérés lorsque la commande est terminée, tandis que dans une transaction explicite, les verrous sont maintenus jusqu'à ce que vous les validiez (pas précis à 100% en raison des niveaux d'isolement, mais c'est le idée générale).
Matan Yungman
Merci pour votre commentaire. La raison pour laquelle je pose ma question est que j'ai lu quelque part que certaines bases de données utilisent MVCC comme moyen de réaliser des transactions ACID, ce qui me semble être un moyen sans verrou de le faire. Dans de tels cas, alors, je ne sais pas quand je voudrais jamais émettre un verrou explicitement. Mais c'est probablement une question distincte. :-)
Laird Nelson
@LairdNelson qui est le niveau d'isolement d'instantané pour SQL Server. Existant, mais pas le mécanisme par défaut pour la concurrence. C'est la valeur par défaut pour Oracle ou Postgresql, IIRC.
Marian
0

Les verrous sont nécessaires et ils font la base de données. Cela empêche les données d'être corrompues ou invalidées lorsque plusieurs utilisateurs essaient de lire tandis que d'autres écrivent dans la base de données. L'isolement transactionnel est généralement implémenté en verrouillant tout ce qui est accessible dans une transaction. Les mauvaises applications de conception font un grand usage du concept de verrouillage de base de données :) !! Pour éviter de verrouiller, concentrez-vous sur votre FK et la disposition des données.

Tout tourne autour de l'ACID: - lisez ceci et cela vous éclaircira! ACID est un ensemble de propriétés que vous souhaitez appliquer lors de la modification d'une base de données.

  • ** Atomicité
  • Cohérence
  • Isolement
  • Durabilité**

Une transaction est un ensemble de modifications associées qui est utilisé pour obtenir certaines des propriétés ACID. Les transactions sont des outils pour obtenir les propriétés ACID.

L'atomicité signifie que vous pouvez garantir que toute une transaction se produit, ou rien ne se passe; vous pouvez effectuer des opérations complexes en une seule unité, tout ou rien, et un crash, une panne de courant, une erreur ou toute autre chose ne vous permettra pas d'être dans un état dans lequel seules certaines des modifications associées se sont produites.

La cohérence signifie que vous garantissez la cohérence de vos données; aucune des contraintes que vous avez sur les données associées ne sera violée.

L'isolement signifie qu'une transaction ne peut pas lire les données d'une autre transaction qui n'est pas encore terminée. Si deux transactions s'exécutent simultanément, chacune verra le monde comme si elle s'exécutait séquentiellement, et si l'une devait lire des données écrites par une autre, elle devra attendre que l'autre soit terminée.

La durabilité signifie qu'une fois la transaction terminée, il est garanti que toutes les modifications ont été enregistrées sur un support durable (tel qu'un disque dur), et le fait que la transaction a été effectuée est également enregistré.

Ainsi, les transactions sont un mécanisme pour garantir ces propriétés; ils sont un moyen de regrouper des actions connexes de telle sorte que, dans son ensemble, un groupe d'opérations puisse être atomique, produire des résultats cohérents, être isolé des autres opérations et être enregistré de manière durable.

Up_One
la source
Merci pour votre commentaire. Je suis au moins passablement conscient des propriétés de l'ACID. Ce que je ne sais toujours pas, c'est: les transactions implémentent-elles ACID en utilisant les mêmes types de verrous que je peux utiliser directement via des LOCKinstructions explicites , ou le font-elles en utilisant un autre mécanisme?
Laird Nelson
Les bases de données offrent un certain nombre de niveaux d'isolement des transactions, qui contrôlent le degré de verrouillage qui se produit lors de la sélection des données: lectures sérialisables, répétables, lecture validée, lecture non validée.
Up_One