Großer Unterschied, TABLOCK
wird versuchen, "geteilte" Sperren zu greifen, und TABLOCKX
exklusive Sperren.
Wenn Sie sich in einer Transaktion befinden und eine exklusive Sperre für eine Tabelle erhalten, z. B.:
SELECT 1 FROM TABLE WITH (TABLOCKX)
Keine anderen Prozesse können irgendwelche abrufen Sperren auf der Tabelle, also alle Abfragen, die versuchen, mit der Tabelle zu kommunizieren, werden blockiert, bis die Transaktion festgeschrieben wird.
TABLOCK
greift nur eine gemeinsame Sperre, gemeinsame Sperren werden freigegeben, nachdem eine Anweisung ausgeführt wurde, wenn Ihre Transaktionsisolation READ COMMITTED
ist (Ursprünglich). Wenn Ihre Isolationsstufe höher ist, zum Beispiel:SERIALIZABLE
, gemeinsame Sperren werden bis zum Ende einer Transaktion gehalten.
Geteilte Sperren sind, hmmm, geteilt. Das bedeutet, dass 2 Transaktionen gleichzeitig Daten aus der Tabelle lesen können, wenn sie beide eine S- oder IS-Sperre auf der Tabelle halten (über TABLOCK
). Wenn jedoch transaction A
hält eine gemeinsame Sperre für eine Tabelle, transaction B
wird nicht in der Lage sein, eine exklusive Sperre zu greifen, bis alle gemeinsamen Sperren freigegeben sind. Lesen Sie unter msdn, welche Schlösser mit welchen kompatibel sind.
Beide Hinweise bewirken, dass die Datenbank granularere Sperren (wie Sperren auf Zeilen- oder Seitenebene) umgeht. Im Prinzip ermöglichen granulare Sperren eine bessere Parallelität. So könnte beispielsweise eine Transaktion Zeile 100 in Ihrer Tabelle und eine andere Zeile 1000 gleichzeitig aktualisieren aus zwei Transaktionen (mit Seitensperren wird es schwierig, aber das können wir überspringen).
Im Allgemeinen sind granulare Sperren das, was Sie wollen, aber manchmal möchten Sie vielleicht die db-Parallelität reduzieren, um die Leistung einer bestimmten Operation zu erhöhen und die Möglichkeit von Deadlocks zu eliminieren.
Im Allgemeinen würden Sie TABLOCK
nicht verwenden oder TABLOCKX
es sei denn, Sie brauchten es unbedingt für einen Grenzfall.