Jeśli wykonuję pojedyncze wywołanie bazy danych SQL Server za pośrednictwem sieci o dużym opóźnieniu, czy z powodu tego opóźnienia wystąpią blokady tabeli? Powiedzmy, że pytam o tabelę A o niektóre rekordy, a SQL Server musi zwrócić te dane w wolnej sieci - czy w tabeli A pojawi się blokada odczytu, gdy serwer wyśle odpowiedź przez sieć, czy też SQL Server zwolni blokadę przed wysłaniem odpowiedź?
Czy odpowiedź byłaby różna w zależności od wielkości odpowiedzi? Gdyby po prostu zwrócił kilka KB w porównaniu do kilkuset MB, czy miałoby to znaczenie?
Utworzenie wyraźnej transakcji, uruchomienie zapytań i zamknięcie transakcji spowodowałoby oczywiście zablokowanie tabel, ponieważ czas trwania transakcji jest skorelowany z moim opóźnieniem.
sql-server
locking
network
Evan M.
źródło
źródło
nolock
podpowiedzi, zawsze będzie blokada . Opóźnienie określa tylko, jak długo zamek będzie trzymany.nolock
, nadal będziesz się zamkiUnless you specify a nolock hint, there will always be a lock.
<- oznacza to, że jeśli używasz nolock, może nie być blokad. Ja tylko wyjaśniłem.Odpowiedzi:
To nie jest dokładne, zależy to od poziomu izolacji.
Domyślnie
READ COMMITTED
blokady nie są wstrzymywane na czas wykonywania instrukcji.READ COMMITTED
nie zapewnia spójności odczytu na poziomie instrukcji, jedyną gwarancją jest to, że nie można odczytać niezaangażowanych danych. Blokada współdzielona jest pobierana i utrzymywana w celu odczytania wiersza, a następnie zwolniona.Chyba że masz typy LOB.
Typy LOB, potencjalnie bardzo duże, nie mogą być buforowane. Blokada współdzielona musi zostać nabyta i utrzymana do czasu wypełnienia oświadczenia, co zasadniczo daje ci
REPEATABLE READ
zachowanie wREAD COMMITTED
.Opóźnienie nie powoduje blokady stołu, nie. Jeśli jednak zostanie uzyskana blokada stołu, opóźnienie ją przedłuży.
Cytując kogoś, kto zna mechanikę tego lepiej niż ja ( @RemusRusanu ):
Tam, gdzie wyniki nie są zużywane tak szybko, jak SQL Server może je dostarczyć, czy to ze względu na klienta, czy sieć, obserwujemy
ASYNC_NETWORK_IO
kumulację oczekiwań. Powtórzmy, że nie wpłynie to na zdobywane blokady, tylko na czas ich trwania.źródło
Odpowiedź Marka rozwiała wiele moich nieporozumień, ale chciałem opublikować moje odkrycia po przetestowaniu tego za pomocą NetBalancer do emulacji opóźnień.
Mój komputer lokalny wywołał zdalny serwer SQL i wykonał zarówno SELECT, jak i INSERT na stole w ramach niewielkiej transakcji. Na zdalnej maszynie podłączyłem się do lokalnej instancji SQL i użyłem pętli WHILE, aby wielokrotnie iterować po tabeli sys.dm_tran_locks, szukając jakichkolwiek blokad w tabeli, z której modyfikowałem i czytałem. Zainstalowałem NetBalancer na serwerze i użyłem go do emulacji opóźnień sieciowych na połączeniu sieciowym serwera.
Oto, co znalazłem:
Z tego wnioskuję, że opóźnienie nie ma znaczenia, dopóki dane mieszczą się w buforze sieciowym. Jeśli SQL musi umieścić dużo danych w buforze sieciowym, opóźnienie spowoduje, że bufor ten utworzy kopię zapasową, a SQL będzie utrzymywał blokady tabeli, dopóki nie umieści wszystkich wyników zapytania w buforze.
źródło
Po uruchomieniu i zakończeniu zapytania przez SQL Server generuje wyniki, umieszcza je w buforze wyjściowym i wysyła do klienta, który następnie pobiera wynik z bufora wyjściowego. SQL Server nie zwolni blokad przechowywanych przez zapytanie, chyba że otrzymane zostanie potwierdzenie od klienta. Co może powodować blokowanie.
Edycja: Evan, możesz odwołać się do tego artykułu pomocy technicznej MS
W sekcji 3
Blokowanie spowodowane przez SPID, którego odpowiednia aplikacja kliencka nie pobrała wszystkich wierszy wyników do zakończenia
Po wysłaniu zapytania do serwera wszystkie aplikacje muszą natychmiast pobrać wszystkie wiersze wyników do zakończenia. Jeśli aplikacja nie pobierze wszystkich wierszy wyników, w tabelach można pozostawić blokady, blokując innych użytkowników. Jeśli używasz aplikacji, która transparentnie przesyła instrukcje SQL na serwer, aplikacja musi pobrać wszystkie wiersze wyników. Jeśli tak się nie stanie (i jeśli nie można tego skonfigurować), rozwiązanie problemu z blokowaniem może być niemożliwe. Aby uniknąć tego problemu, można ograniczyć źle działające aplikacje do bazy danych raportowania lub wspomagania decyzji.
źródło
SELECT *
od niego wREAD COMMITTED
jednym połączeniu SSMS, monitor blokuje się od drugiego. Ile kiedykolwiek zamków widzisz?