Bei der Untersuchung der Verwendung von Tabellenhinweisen bin ich auf diese beiden Fragen gestoßen:
Antworten auf beide Fragen besagen, dass (UPDLOCK, HOLDLOCK)
andere Prozesse bei der Verwendung keine Daten in dieser Tabelle lesen können, aber ich habe dies nicht gesehen. Zum Testen habe ich eine Tabelle erstellt und zwei SSMS-Fenster gestartet. Im ersten Fenster habe ich eine Transaktion ausgeführt, die anhand verschiedener Tabellenhinweise aus der Tabelle ausgewählt wurde. Während die Transaktion ausgeführt wurde, habe ich im zweiten Fenster verschiedene Anweisungen ausgeführt, um zu sehen, welche blockiert werden würden.
Die Testtabelle:
CREATE TABLE [dbo].[Test](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Value] [nvarchar](50) NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Aus SSMS-Fenster 1:
BEGIN TRANSACTION
SELECT * FROM dbo.Test WITH (UPDLOCK, HOLDLOCK)
WAITFOR DELAY '00:00:10'
COMMIT TRANSACTION
Aus SSMS-Fenster 2 (führte eine der folgenden Aktionen aus):
SELECT * FROM dbo.Test
INSERT dbo.Test(Value) VALUES ('bar')
UPDATE dbo.Test SET Value = 'baz' WHERE Value = 'bar'
DELETE dbo.Test WHERE Value= 'baz'
Auswirkung verschiedener Tabellenhinweise auf Anweisungen in Fenster 2:
(UPDLOCK) (HOLDLOCK) (UPDLOCK, HOLDLOCK) (TABLOCKX)
---------------------------------------------------------------------------
SELECT not blocked not blocked not blocked blocked
INSERT not blocked blocked blocked blocked
UPDATE blocked blocked blocked blocked
DELETE blocked blocked blocked blocked
Habe ich die Antworten in diesen Fragen falsch verstanden oder bei meinen Tests einen Fehler gemacht? Wenn nicht, warum würden Sie (UPDLOCK, HOLDLOCK)
vs. (HOLDLOCK)
allein verwenden?
Weitere Erklärung dessen, was ich erreichen möchte:
Ich möchte Zeilen aus einer Tabelle auswählen und verhindern, dass die Daten in dieser Tabelle während der Verarbeitung geändert werden. Ich ändere diese Daten nicht und möchte, dass Lesevorgänge stattfinden.
Diese Antwort besagt eindeutig, dass (UPDLOCK, HOLDLOCK)
Lesevorgänge blockiert werden (nicht das, was ich will). Die Kommentare zu dieser Antwort implizieren, HOLDLOCK
dass dies das Lesen verhindert. Um zu versuchen, die Auswirkungen der Tabellenhinweise besser zu verstehen und zu sehen, ob UPDLOCK
allein das tun würde, was ich wollte, habe ich das obige Experiment durchgeführt und Ergebnisse erhalten, die diesen Antworten widersprechen.
Derzeit glaube ich, dass (HOLDLOCK)
ich das verwenden sollte, aber ich befürchte, dass ich einen Fehler gemacht oder etwas übersehen habe, das mich in Zukunft beißen wird, daher diese Frage.
quelle
UPDLOCK wird verwendet, wenn Sie eine oder mehrere Zeilen während einer select-Anweisung für eine zukünftige Update-Anweisung sperren möchten. Das zukünftige Update könnte die nächste Anweisung in der Transaktion sein.
Andere Sitzungen können die Daten weiterhin sehen. Sie können einfach keine Sperren erhalten, die mit UPDLOCK und / oder HOLDLOCK nicht kompatibel sind.
Sie verwenden UPDLOCK, wenn Sie möchten, dass andere Sitzungen die gesperrten Zeilen nicht ändern. Es schränkt ihre Fähigkeit ein, gesperrte Zeilen zu aktualisieren oder zu löschen.
Sie verwenden HOLDLOCK, wenn Sie verhindern möchten, dass andere Sitzungen die angezeigten Daten ändern. Dies schränkt die Möglichkeit ein, die gesperrten Zeilen einzufügen, zu aktualisieren oder zu löschen. Auf diese Weise können Sie die Abfrage erneut ausführen und dieselben Ergebnisse anzeigen.
quelle
(UPDLOCK,HOLDLOCK)
Block lautet, und gibt es einen Grund,(UPDLOCK,HOLDLOCK)
statt nur zu verwenden(HOLDLOCK)
?