Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Verwirrt über UPDLOCK, HOLDLOCK

Warum würde UPDLOCK Auswahlen blockieren? Die Sperrkompatibilitätsmatrix zeigt deutlich N für den S/U- und U/S-Konflikt, wie in No Conflict .

Was den HOLDLOCK-Hinweis betrifft, so heißt es in der Dokumentation:

HOLDLOCK:Entspricht SERIALIZABLE. Weitere Informationen finden Sie weiter unten in diesem Thema unter SERIALIZABLE.

...

SERIALIZABLE:... Der Scan wird mit derselben Semantik durchgeführt wie eine Transaktion, die auf der Isolationsstufe SERIALIZABLE ausgeführt wird...

und das Thema Transaktionsisolationsstufe erklärt, was SERIALIZABLE bedeutet:

Keine anderen Transaktionen können Daten ändern, die von der aktuellen Transaktion gelesen wurden, bis die aktuelle Transaktion abgeschlossen ist.

Andere Transaktionen können keine neuen Zeilen mit Schlüsselwerten einfügen, die in den Bereich der Schlüssel fallen würden, die von Anweisungen in der aktuellen Transaktion gelesen werden, bis die aktuelle Transaktion abgeschlossen ist.

Daher wird das Verhalten, das Sie sehen, perfekt durch die Produktdokumentation erklärt:

  • UPDLOCK blockiert weder gleichzeitiges SELECT noch INSERT, blockiert jedoch jedes UPDATE oder DELETE der von T1 ausgewählten Zeilen
  • HOLDLOCK bedeutet SERALIZABLE und erlaubt daher SELECTS, blockiert aber auch UPDATE und DELETES der von T1 ausgewählten Zeilen wie jedes INSERT in dem von T1 ausgewählten Bereich (das ist die gesamte Tabelle, also beliebig). einfügen).
  • (UPDLOCK, HOLDLOCK):Ihr Experiment zeigt nicht, was zusätzlich zum obigen Fall blockieren würde, nämlich eine weitere Transaktion mit UPDLOCK in T2 :
    SELECT * FROM dbo.Test WITH (UPDLOCK) WHERE ...
  • TABLOCKX braucht keine Erklärungen

Die eigentliche Frage ist, was versuchen Sie zu erreichen ? Das Herumspielen mit Sperrhinweisen ohne ein absolut vollständiges 110%-Verständnis der Sperrsemantik schreit nach Ärger...

Nach OP bearbeiten:

Ich möchte Zeilen aus einer Tabelle auswählen und verhindern, dass die Daten in dieser Tabelle geändert werden, während ich sie verarbeite.

Dann sollten Sie eine der höheren Transaktionsisolationsstufen verwenden. REPEATABLE READ verhindert, dass die gelesenen Daten geändert werden. SERIALIZABLE verhindert, dass die von Ihnen gelesenen Daten geändert werden und neue Daten werden nicht eingefügt. Die Verwendung von Transaktionsisolationsstufen ist der richtige Ansatz, im Gegensatz zur Verwendung von Abfragehinweisen. Kendra Little hat ein schönes Poster, das die Isolationsstufen erklärt.