Załóżmy, że mam następujące długo działające zapytanie
UPDATE [Table1]
SET [Col1] = 'some value'
WHERE [Col2] -- some clause which selects thousands of rows
i załóżmy, że następujące zapytanie jest wykonywane podczas działania powyższego zapytania
SELECT *
FROM [Table1]
Czy pierwsze zapytanie uniemożliwia uruchomienie drugiego zapytania do momentu wykonania pierwszego zapytania? Jeśli tak, to czy pierwsze zapytanie uniemożliwia uruchomienie drugiego zapytania na wszystkich wierszach, czy tylko wierszach objętych klauzulą WHERE?
EDYTOWAĆ:
Załóżmy, że drugie zapytanie to
SELECT [Col1], [Col2]
FROM [Table1]
WHERE [Col2] -- some clause whose matching elements overlap those from
-- the clause in the first query and which has additional matching elements
źródło
SELECT * FROM Table1
jeśli dokładnie tego potrzebuję?*
samo w sobie jest złą praktyką, ponieważ gdy zmienia się struktura tabeli, aplikacja zwykle się psuje (w rezultacie pojawiają się nieoczekiwane kolumny).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 drugiejSELECT
, wzajemnie się wykluczającej lub w inny sposób, interakcje między tymi dwoma zapytaniami będą w dużej mierze takie same.W osobnej sesji uruchom następujące polecenie:
Możesz sprawdzić blokady, które są obecnie
sp_lock
w użyciu, najlepiej podczas kolejnej osobnej sesji:Powinieneś zobaczyć
KEY
blokadę typu trzymaną przez pająka wykonującego transakcję wstawiania wX
trybie (wyłącznym), aby nie pomylić jej z innymiIX
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ęcWAIT
ażX
bezbarwnych zamek, uniemożliwiających innymX
(lubU
) 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ącym
READ 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 .
źródło
WITH (NOLOCK)
tym przypadku pomocne byłoby słowo ostrzeżenia o używaniu . Więcej informacji można znaleźć na stronach brentozar.com/archive/2011/11/… i brentozar.com/archive/2013/02/ ...WITH (NOLOCK)
podpowiedź nie zwraca brudnych stron z pamięci, które nie zostały zatwierdzone . W rzeczywistości odczytuje wiersze z tabeli (na dysku lub w pamięci podręcznej) bez blokowania autorom aktualizacji i dodawania wierszy do stron używanych przez tabelę.