Il livello di isolamento serializzabile di SQL Server blocca l'intera tabella


9

Io e un mio collega abbiamo discusso delle implicazioni dell'uso del livello di isolamento serializzabile. Ha detto che ha bloccato l'intero tavolo, ma non sono d'accordo sul fatto che dirgli che potrebbe potenzialmente, ma cerca di applicare i blocchi di intervallo e non applica la vera serializzazione come spiegato qui: Il livello di isolamento serializzabile .

Non riesco a trovare nulla nei documenti neanche per "blocca l'intera tabella": SET TRANSACTION ISOLATION LEVEL .

Il documento afferma un sacco di cose riguardanti i blocchi di intervallo, quindi in teoria potresti bloccare l'intero tavolo semplicemente avendo un blocco di intervallo che blocca l'intero intervallo di valori possibili nella tabella, ma non blocca la tabella.

Ho completamente sbagliato qui? In effetti, blocca l'intera tabella (o tabelle)?

Risposte:


16

Escalation, però

L'escalation dei blocchi con livello di isolamento serializzabile può verificarsi allo stesso modo di altri livelli di isolamento.

  • Gli indici corretti possono aiutare a evitare l'escalation dei blocchi fino a un certo punto
  • Il blocco di molti indici aumenta la probabilità di escalation dei blocchi; il conteggio è cumulativo tra gli oggetti per una singola istruzione

Alcuni esempi rapidi usando una singola tabella con un singolo indice. ID è la chiave primaria e l'indice cluster sulla tabella.

Una fila

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

Per un singolo valore ID, il blocco è minimo.

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

Righe multiple

Ma i blocchi aumenteranno se iniziamo a lavorare in intervalli:

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

Ora abbiamo più blocchi esclusivi su più chiavi:

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

Molto più righe

Questo continuerà fino a quando non raggiungiamo un punto di non ritorno:

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

Si tenta di bloccare l'escalation e ha esito positivo:

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

Fai attenzione

È importante separare due concetti qui: il livello di isolamento sarà serializzabile indipendentemente dal tipo di blocchi. La query sceglie il livello di isolamento e il motore di archiviazione sceglie i blocchi. La serializzazione non comporterà sempre blocchi dell'intervallo: il motore di archiviazione può scegliere qualsiasi tipo di blocco rispetti ancora il livello di isolamento.


5

Se esiste un indice in un predicato di ricerca, potrebbe essere utilizzato per i blocchi dell'intervallo .

Vale a dire, blocco dalla prima riga alla successiva nel raggio. E da quella successiva alla terza riga, ecc. Fino all'ultima riga dell'intervallo. Quindi essenzialmente un numero di blocchi di riga, ma blocca l'intervallo dagli inserti anche per valori "intermedi" (blocco dell'intervallo).

Perché ciò avvenga, è necessario che tu (SQL Server) disponga di un indice con cui lavorare. Senza gli indici per eseguire il blocco (indici sui predicati), (da quello che so) otterrete i blocchi delle tabelle.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.