Czy proste zapytanie wybierz nabywa blokady?

14

Jestem bardzo nowy w SQL Server i chciałbym zrozumieć, czy poniższa, bardzo prosta selectinstrukcja zabierze jakieś blokady.

Select * from Student;

Proszę rozważyć przypadek, w którym instrukcja nie działałaby w begin tranbloku.

Nowy programista
źródło
1
To jest o wiele bardziej skomplikowane pytanie, niż mogłoby się wydawać. Odpowiedź zależy od wielu rzeczy (jaki jest poziom izolacji transakcji sesji? Czy włączona jest izolacja zatwierdzonej migawki odczytu? Czy skanowany indeks ma ustawione opcje zapobiegające blokowaniu wierszy lub stron?), A nawet może się zmieniać podczas działania instrukcji (ile wiersze są w tabeli? czy tabela jest podzielona na partycje?). Oto dobry punkt, aby zacząć czytać.
Jon Seigel

Odpowiedzi:

5

Tak, domyślnie przyjmuje blokadę współdzieloną w wierszach, które odczytuje (przyjmuje również blokadę zamierzoną współdzieloną na wszystkich stronach indeksu klastrowanego, który będzie czytać), aby zapobiec nieczytelnym odczytom. Istnieją jednak sposoby na obejście tego (SQL Server ma wskazówkę nolock). Jeśli instrukcja nie znajduje się w BEGIN TRAN, blokada jest zwalniana po uruchomieniu instrukcji SELECT.

Więcej informacji można znaleźć tutaj:

http://msdn.microsoft.com/en-us/library/ms184286(v=sql.105).aspx http://www.sqlteam.com/article/introduction-to-locking-in-sql-server

Bez zmarszczek
źródło
Ponadto można również ustawić poziom izolacji transakcji na odczyt niezaangażowany.
Zane
1
Więc jeśli SELECT odczytuje dziesięć wierszy, czy dziesięć współużytkowanych blokad jest utrzymywanych do momentu odczytania wszystkich dziesięciu wierszy, czy też są one uzyskiwane i zwalniane na wiersz?
Ian Warburton,
26

Chciałbym zrozumieć, czy poniższa, bardzo prosta instrukcja select zabierze jakieś blokady

Powszechnym błędem jest przekonanie, że SELECTzapytanie działające na domyślnym READ COMMITTEDpoziomie izolacji transakcji zawsze przyjmuje wspólne blokady, aby zapobiec nieczytelnym odczytom.

SQL Server może uniknąć przyjmowania współdzielonych blokad na poziomie wiersza, gdy nie ma niebezpieczeństwa odczytu niezaangażowanych danych bez nich (chociaż blokady Intent-Shared (IS) wyższego poziomu są nadal podejmowane).

Nawet jeśli zostaną podjęte blokady wierszy współdzielonych (być może dlatego, że inna jednoczesna transakcja zmodyfikowała stronę, na której znajduje się wiersz), można je zwolnić na długo przed zakończeniem SELECTinstrukcji.

W większości przypadków wiersz jest „odblokowywany” tuż przed przetworzeniem przez serwer następnego rzędu. Istnieją okoliczności, w których blokady dzielone podejmowane na domyślnym poziomie izolacji są utrzymywane na końcu bieżącego wyciągu, ale nie na końcu transakcji .

Zastąpienie obecnego poziomu izolacji NOLOCKwskazówkami dotyczącymi tabeli jest prawie zawsze złym pomysłem .

Blokowanie jest szczegółem implementacji. W razie potrzeby program SQL Server przyjmuje blokady , aby upewnić się, że spełnia semantyczne gwarancje zapewniane przez bieżący poziom izolacji . Z pewnością są chwile, w których warto wiedzieć trochę o tym, dlaczego zamki są podejmowane, ale próba ich przewidzenia często przynosi efekt przeciwny do zamierzonego.

SQL Server zapewnia szeroki zakres poziomów izolacji; wybierz ten, który zapewnia gwarancje i zachowania, których potrzebują Twoi klienci danych.

Paul White 9
źródło