web-dev-qa-db-fra.com

Le niveau d'isolement sérialisable de SQL Server verrouille-t-il toute la table

Un de mes collègues et moi avons discuté des implications de l'utilisation du niveau d'isolement sérialisable. Il a dit qu'il avait verrouillé toute la table, mais je n'étais pas d'accord pour lui dire que cela pouvait potentiellement mais il essayait d'appliquer des verrous de plage et il n'appliquait pas la véritable sérialisation comme expliqué ici: The Serializable Isolation Level .

Je ne trouve rien non plus dans la documentation pour les "verrous de la table": SET TRANSACTION ISOLATION LEVEL .

Le document énonce un tas de choses concernant les verrous de plage, donc en théorie, vous pouvez verrouiller toute la table en ayant simplement un verrou de plage qui verrouille toute la plage de valeurs possibles dans la table, mais il ne verrouille pas la table.

Suis-je complètement faux ici? Verrouille-t-il en fait la table entière (ou les tables)?

9
mslot

Escalade, cependant

Escalade de verrouillage sous un niveau d'isolement sérialisable peut se produire de la même manière qu'avec d'autres niveaux d'isolement.

  • Des index corrects peuvent aider à éviter l'escalade des verrous jusqu'à un certain point
  • Le verrouillage de nombreux index augmentera la probabilité d'escalade des verrous; le nombre est cumulatif entre les objets pour une seule instruction

Quelques exemples rapides utilisant une seule table avec un seul index. Id est la clé primaire et l'index cluster de la table.

Une rangée

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN

UPDATE c
SET c.Score = 2147483647 
FROM dbo.Comments AS c
WHERE c.Id = 138; --One value

ROLLBACK

Pour une seule valeur Id, le verrouillage est minimal.

+--------------+---------------+---------------+-------------+
| request_mode | locked_object | resource_type | total_locks |
+--------------+---------------+---------------+-------------+
| RangeX-X     | Comments      | KEY           |           1 |
| IX           | Comments      | OBJECT        |           1 |
| IX           | Comments      | PAGE          |           1 |
+--------------+---------------+---------------+-------------+

Plusieurs lignes

Mais les verrous augmenteront si nous commençons à travailler dans des plages:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN

UPDATE c
SET c.Score = 2147483647 
FROM dbo.Comments AS c
WHERE c.Id BETWEEN 1 AND 5000; -- Small range

ROLLBACK

Nous avons maintenant des verrous plus exclusifs sur plus de clés:

+--------------+---------------+---------------+-------------+
| request_mode | locked_object | resource_type | total_locks |
+--------------+---------------+---------------+-------------+
| RangeX-X     | Comments      | KEY           |        2429 |
| IX           | Comments      | OBJECT        |           1 |
| IX           | Comments      | PAGE          |          97 |
+--------------+---------------+---------------+-------------+

Beaucoup plus de lignes

Cela continuera jusqu'à ce que nous atteignions un point de basculement:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN

UPDATE c
SET c.Score = 2147483647 
FROM dbo.Comments AS c
WHERE c.Id BETWEEN 1 AND 11655; --Larger range

ROLLBACK

L'escalade de verrous est tentée et réussie:

+--------------+---------------+---------------+-------------+
| request_mode | locked_object | resource_type | total_locks |
+--------------+---------------+---------------+-------------+
| X            | Comments      | OBJECT        |           1 |
+--------------+---------------+---------------+-------------+

Faites attention

Il est important de séparer deux concepts ici: le niveau d'isolement sera sérialisable quel que soit le type de verrous pris. La requête choisit le niveau d'isolement et le moteur de stockage choisit les verrous. La sérialisation ne se traduira pas toujours par des verrous de plage - le moteur de stockage peut choisir le type de verrous qui respecte toujours le niveau d'isolement.

16
Erik Darling

S'il existe un index sur un prédicat de recherche, il peut être utilisé pour plage de verrous.

C'est-à-dire, verrouiller de la première rangée à la suivante dans la plage. Et de cela à côté de la troisième rangée, etc. Jusqu'à la dernière rangée de la plage. Donc, essentiellement un certain nombre de verrous de ligne, mais il bloque également la plage des insertions pour les valeurs "intermédiaires" (verrouillage de la plage).

Pour cela, vous (SQL Server) devez disposer d'un index avec lequel travailler. Sans index pour effectuer le verrouillage (index sur les prédicats), vous obtiendrez (d'après ce que je sais) des verrous de table.

5
Tibor Karaszi