Badając zastosowanie podpowiedzi do tabeli , natknąłem się na te dwa pytania:
Odpowiedzi na oba pytania mówią, że podczas używania (UPDLOCK, HOLDLOCK)
inne procesy nie będą w stanie odczytać danych z tej tabeli, ale tego nie widziałem. Aby przetestować, stworzyłem tabelę i uruchomiłem dwa okna SSMS. W pierwszym oknie przeprowadziłem transakcję, która została wybrana z tabeli przy użyciu różnych wskazówek dotyczących tabeli. Podczas trwania transakcji w drugim oknie uruchomiłem różne instrukcje, aby zobaczyć, które zostaną zablokowane.
Tabela testowa:
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]
Z okna 1 programu SSMS:
BEGIN TRANSACTION
SELECT * FROM dbo.Test WITH (UPDLOCK, HOLDLOCK)
WAITFOR DELAY '00:00:10'
COMMIT TRANSACTION
Z okna SSMS 2 (uruchomiono jedną z następujących czynności):
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'
Wpływ różnych wskazówek dotyczących tabeli na instrukcje uruchamiane w oknie 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
Czy źle zrozumiałem odpowiedzi udzielone w tych pytaniach lub popełniłem błąd podczas testu? Jeśli nie, dlaczego miałbyś używać (UPDLOCK, HOLDLOCK)
vs. (HOLDLOCK)
sam?
Dalsze wyjaśnienie tego, co próbuję osiągnąć:
Chciałbym wybrać wiersze z tabeli i zapobiec modyfikowaniu danych w tej tabeli podczas jej przetwarzania. Nie modyfikuję tych danych i chciałbym zezwolić na odczytywanie.
Ta odpowiedź wyraźnie mówi, że (UPDLOCK, HOLDLOCK)
zablokuje odczyty (nie to, czego chcę). Komentarze do tej odpowiedzi sugerują, że ona HOLDLOCK
uniemożliwia odczytanie. Aby lepiej zrozumieć skutki podpowiedzi tabeli i zobaczyć, czy UPDLOCK
sam zrobi to, co chcę, przeprowadziłem powyższy eksperyment i otrzymałem wyniki, które są sprzeczne z tymi odpowiedziami.
Obecnie uważam, że (HOLDLOCK)
to jest to, czego powinienem użyć, ale obawiam się, że mogłem popełnić błąd lub przeoczyć coś, co w przyszłości będzie mnie gryźć, stąd to pytanie.
źródło
UPDLOCK jest używany, gdy chcesz zablokować wiersz lub wiersze podczas instrukcji select dla przyszłej instrukcji aktualizacji. Przyszła aktualizacja może być kolejnym oświadczeniem w transakcji.
Inne sesje nadal mogą wyświetlać dane. Po prostu nie mogą uzyskać blokad, które są niekompatybilne z UPDLOCK i / lub HOLDLOCK.
Używasz UPDLOCK, gdy chcesz uniemożliwić innym sesjom zmianę zablokowanych wierszy. Ogranicza ich możliwość aktualizowania lub usuwania zablokowanych wierszy.
Używasz HOLDLOCK, gdy chcesz uniemożliwić innym sesjom zmianę jakichkolwiek danych, na które patrzysz. Ogranicza ich możliwość wstawiania, aktualizowania lub usuwania zablokowanych wierszy. Dzięki temu możesz ponownie uruchomić zapytanie i zobaczyć te same wyniki.
źródło
(UPDLOCK,HOLDLOCK)
blok jest czytany, i czy jest powód, aby używać(UPDLOCK,HOLDLOCK)
zamiast po prostu(HOLDLOCK)
?