Dies ist eher ein Beispiel, bei dem TABLOCK bei mir und TABLOCKX nicht funktioniert hat.
Ich habe 2 Sitzungen, die beide die Standardisolationsstufe (READ COMMITTED) verwenden:
Sitzung 1 ist eine explizite Transaktion, die Daten von einem Verbindungsserver in eine Reihe von Tabellen in einer Datenbank kopiert und deren Ausführung einige Sekunden dauert. [Beispiel, es löscht Fragen] Sitzung 2 ist eine Einfügeanweisung, die einfach Zeilen in eine Tabelle einfügt, an der Sitzung 1 keine Änderungen vornimmt. [Beispiel, es fügt Antworten ein].
(In der Praxis werden mehrere Sitzungen gleichzeitig in die Tabelle eingefügt, während Sitzung 1 die Transaktion ausführt.)
Sitzung 1 muss die Tabelle abfragen, in die Sitzung 2 eingefügt wird, da keine Datensätze gelöscht werden können, die von Einträgen abhängen, die von Sitzung 2 hinzugefügt wurden. [Beispiel: Löschen von Fragen, die nicht beantwortet wurden].
Während also Sitzung 1 ausgeführt wird und Sitzung 2 versucht einzufügen, verliert Sitzung 2 jedes Mal einen Deadlock.
Eine Löschanweisung in Sitzung 1 könnte also ungefähr so aussehen: DELETE tblA FROM tblQ LEFT JOIN tblX on ... LEFT JOIN tblA a ON tblQ.Qid = tblA.Qid WHERE ... a.QId IS NULL und ...
Der Deadlock scheint durch einen Konflikt zwischen der Abfrage von tblA verursacht zu werden, während Sitzung 2, [3, 4, 5, ..., n] versuchen, in tblA einzufügen.
In meinem Fall könnte ich die Isolationsstufe der Transaktion von Sitzung 1 so ändern, dass sie SERIALISIERBAR ist. Als ich dies tat: Der Transaktionsmanager hat die Unterstützung für Remote- / Netzwerktransaktionen deaktiviert.
Ich könnte also den Anweisungen in der akzeptierten Antwort hier folgen, um das Problem zu umgehen: Der Transaktionsmanager hat die Unterstützung für Remote- / Netzwerktransaktionen deaktiviert
Aber a) ich war überhaupt nicht damit zufrieden, die Isolationsstufe auf SERIALIZABLE zu ändern - angeblich verschlechtert dies die Leistung und kann andere Konsequenzen haben, die ich nicht berücksichtigt habe. B) Ich habe nicht verstanden, warum dies plötzlich zu einer Transaktion geführt hat ein Problem, das auf Verbindungsservern funktioniert, und c) ich weiß nicht, welche möglichen Lücken ich durch die Aktivierung des Netzwerkzugriffs öffnen könnte.
Es schien nur 6 Abfragen innerhalb einer sehr großen Transaktion zu geben, die die Probleme verursachen.
Also habe ich über TABLOCK und TabLOCKX gelesen.
Ich war mir der Unterschiede nicht ganz sicher und wusste nicht, ob beides funktionieren würde. Aber es schien so. Zuerst habe ich TABLOCK ausprobiert und es schien keinen Unterschied zu machen. Die konkurrierenden Sitzungen erzeugten die gleichen Deadlocks. Dann habe ich TABLOCKX ausprobiert und keine Deadlocks mehr.
An sechs Stellen musste ich also nur ein WITH (TABLOCKX) hinzufügen.
Eine Löschanweisung in Sitzung 1 könnte also ungefähr so aussehen: LÖSCHEN von tblA VON tblQ q LINKS VERBINDEN tblX x on ... LINKS VERBINDEN tblA a WITH (TABLOCKX) ON tblQ.Qid = tblA.Qid WHERE ... a.QId IST NULL und ...
TABLOCK
handelt sich um eine gemeinsam genutzte Sperre, mit der mehrere Clients gleichzeitig Daten in die Tabelle laden können. Eine exklusive Sperre nicht.