Edycja: Jak wskazuje @MaxVernon , poniższe stwierdzenie nie jest w żaden sposób sugestią użycia NOLOCK , a ja bardzo dobrze powinienem wspomnieć o ustawieniu poziomu transakcji READ UNCOMMITED
i pozostawieniu negatywnej konotacji tam, niż NOLOCK
o tym wspominając . Tak jak pierwotnie napisano:
Szybka i prosta odpowiedź brzmi: „Tak, pierwsze zapytanie zablokuje drugie zapytanie, chyba że zostanie określona konkretna wskazówka dotycząca indeksu ( NOLOCK , czasami nazywana„ nieczytelnym odczytem ”) lub poziom izolacji transakcji drugiego zapytania jest ustawiony na READ UNCOMMITED
(który działa identycznie), nie."
W odpowiedzi na dodatkowe szczegóły przedstawione w pytaniu, które wymagają włączenia WITH
klauzuli drugiej SELECT
, wzajemnie się wykluczającej lub w inny sposób, interakcje między tymi dwoma zapytaniami będą w dużej mierze takie same.
IF NOT EXISTS ( SELECT 1
FROM sys.objects
WHERE name = 'Foo'
AND type = 'U' )
BEGIN
--DROP TABLE dbo.Foo;
CREATE TABLE dbo.Foo
(
Foo_PK BIGINT IDENTITY( 1, 1 ) NOT NULL,
PRIMARY KEY ( Foo_PK ),
Bar BIT,
x BIT,
y BIT,
z BIT
);
CREATE NONCLUSTERED INDEX IX_Foo_x
ON dbo.Foo ( x );
INSERT INTO dbo.Foo ( Bar, x, y, z )
VALUES ( 1, 1, 1, 1 ), ( 0, 0, 0, 0 );
END;
GO
BEGIN TRANSACTION;
UPDATE dbo.Foo
SET y = 0
WHERE x = 1;
-- COMMIT TRANSACTION;
W osobnej sesji uruchom następujące polecenie:
SELECT *
FROM dbo.Foo WITH ( NOLOCK );
GO
SELECT *
FROM dbo.Foo;
Możesz sprawdzić blokady, które są obecnie sp_lock
w użyciu, najlepiej podczas kolejnej osobnej sesji:
EXECUTE dbo.sp_lock;
Powinieneś zobaczyć KEY
blokadę typu trzymaną przez pająka wykonującego transakcję wstawiania w X
trybie (wyłącznym), aby nie pomylić jej z innymi IX
blokadami (celowo-wyłącznymi). Dokumentacja blokady wskazuje, że chociaż KEY
blokada jest specyficzna dla zakresu, zapobiega ona również wstawianiu lub aktualizowaniu odpowiednich kolumn przez inne transakcje, zmieniając zawarte w nich dane, tak aby mogła mieścić się w tym zakresie pierwotnego zapytania. Ponieważ sama blokada jest wyłączna, pierwsze zapytanie uniemożliwia dostęp do zasobu z dowolnego innej transakcji równoległej. W efekcie wszystkie wiersze kolumny są zablokowane, niezależnie od tego, czy mieszczą się w zakresie określonym przez pierwsze zapytanie.
S
Zamek jest w posiadaniu drugiej sesji będzie więc WAIT
aż X
bezbarwnych zamek, uniemożliwiających innym X
(lub U
) Blokada przed podjęte na tego zasobu z innego jednoczesnego spid przed druga sesja kończy operację odczytu, uzasadniających istnienieS
zamka.
Teraz edycja dla jasności: Chyba że się mylę z tym, co jest brudnym odczytem z krótkiego opisu wspomnianych tutaj zagrożeń ... Edytuj 3 : Właśnie zdałem sobie sprawę, że nie rozważam wpływu punktu kontrolnego w tle, który zapisuje jako jeszcze niezaangażowanej transakcji na dysk, więc tak, moje wyjaśnienie było mylące.
W drugim zapytaniu pierwsza partia może (iw tym przypadku zwróci) nieprzydzielone dane. Druga partia, działająca na domyślnym poziomie izolacji transakcji wynoszącymREAD COMMITED
zwróci się dopiero po zakończeniu zatwierdzenia lub wycofania w pierwszej sesji.
Stąd można patrzeć na swoich planów kwerend i związanych z nimi poziomów blokady, ale jeszcze lepiej, można przeczytać o zamki w SQL Server tutaj .
SELECT * FROM Table1
jeśli dokładnie tego potrzebuję?