Używam SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
w większości moich ogólnych zapytań SQL, głównie dlatego, że zostały mi one wywiercone podczas oryginalnej nauki języka.
Z mojego zrozumienia ten poziom izolacji działa w ten sam sposób, z którego WITH (NO LOCK)
jednak zawsze korzystam SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
.
- Czy kiedykolwiek czas, że należy przy użyciu
WITH (NO LOCK)
ponadSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
. - Czy
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
powstrzymuje innych użytkowników przed blokowaniem się w tabelach, które czytam? - Jeśli
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
służy do zatrzymywania blokad, ale czytam tylko dane, jaki jest sens ich używania? Czy to tylko zapytania systemowe wymagające wygenerowania blokad? Czy warto go używać podczas uruchamiania zapytań, które zwrócą się powiedzmy za 5-10 sekund? - Powiedziano mi, aby nie używać
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
podczas odczytu danych, które zostaną wykorzystane w aktualizacjach, prawdopodobnie w celu uniknięcia aktualizacji brudnych danych. Czy to byłby jedyny powód? - Z typem bazy danych, nad którą pracuję, istnieje środowisko produkcyjne i testowe. Bardzo rzadko wysyłamy zapytania do środowiska produkcyjnego, ale gdy zajdzie taka potrzeba, zwykle używam
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
w moim zapytaniu. Rozumiem, że przy tym możliwe są brudne odczyty. Oprócz otrzymywania danych z powrotem, które mogą nie zostać przypisane do bazy danych (a zatem wyrzucić moje wyniki), jakie inne rodzaje „brudnych odczytów” mogą być możliwe?
Przepraszam za masowe pytania.
sql-server
isolation-level
dmoney
źródło
źródło
READ UNCOMMITTED
wszędzie, w dokładnie taki sam sposób, jak nie używałbymWITH (NOLOCK)
wszędzie (to w zasadzie ta sama rzecz) blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhereOdpowiedzi:
To okropne, że nauczyłeś się tego w ten sposób (przepraszam!).
READ UNCOMMITTED
przeczytajmy każdy wiersz, tak. Nawet ci, którzy są obecnie stosowane wINSERT
,UPDATE
,DELETE
operacji. Jest to bardzo przydatne, jeśli chceszSELECT
rzucić okiem na niektóre dane lub w krytycznych misjach - informacje, w których blok byłby bardzo szkodliwy.W rzeczywistości ryzykujesz uczciwość. Może się zdarzyć, że przeczytasz wiersz, który jest obecnie używany do usunięcia lub zmiany. Może się również wydawać, że odczytałeś niewłaściwą wartość. To może być naprawdę rzadkie, ale może się zdarzyć. Co mam na myśli? Pomyśl o rzędzie, który jest bardzo szeroki (ma wiele kolumn z wieloma długimi kolumnami
nvarchar
). Aktualizacja występuje w tym wierszu i ustawia nowe wartości. W rzadkich przypadkach może się zdarzyć, że przeczytasz tylko pół rzędu. Inna rzecz może się zdarzyć na przykład, jeśli użytkownik zmieni swoje wartości logowania. Zmienia swoją pocztę + hasło. Poczta jest już ustawiona, ale hasło nie jest. W ten sposób masz niespójny stan.Sugerowałbym zapomnieć o
READ UNCOMMITTED
. Po prostu użyj go tam, gdzie jest naprawdę potrzebny.Inną alternatywą dla ciebie może być włączenie
READ_COMMITTED_SNAPSHOT
opcji bazy danych - do tego możesz użyćREAD COMMITTED SNAPSHOT
ze względu na włączone wersjonowanie wierszy w tempdb. W ten sposób po prostu czytasz inną (starszą) wersję wiersza. To nie zablokuje twoich zapytań. Ale może się zdarzyć, że odczytasz również starą wartość, ale spójną starą wartość.WITH(READPAST)
Zamiast tego może być inny pomysłWITH(NOLOCK)
. Przeczytasz stary stan tabeli (trochę jak wSNAPSHOT ISOLATION
), ale zamiast tego pominiesz wszystkie aktualnie zablokowane wiersze.źródło
SNAPSHOT ISOLATION
nie musi być włączony, aby się włączyćREAD COMMITTED SNAPSHOT
.READ COMMITTED SNAPSHOT
Należy włączyć tylko opcję bazy danych, aby wersjonowanie wierszy zamiast blokować spójność odczytu, unikając konieczności niepoprawnych odczytów.Jak stwierdzono w zaakceptowanej odpowiedzi, zapomnij o używaniu poziomu izolacji ODCZYTAJ NIEDOZWOLONY (z wyjątkiem gdy jest to naprawdę potrzebne), ponieważ ryzykujesz odczytaniem niewłaściwych danych. Ale aby odpowiedzieć na trzeci punkt w twoim pytaniu, przydatne są dwie sytuacje:
Podczas pisania i testowania pakietów SSIS programu SQL Server kroki pakietu mogą być zawinięte w transakcję. Jeśli testujesz pakiet, uruchamiając go krok po kroku w debuggerze SSIS, możesz sprawdzić tabele, gdy są tam blokady. Użycie USTAW POZIOMU IZOLACJI ODCZYTUJE NIEZGODNE Z NIMI pozwala używać SQL Server Manager Studio do sprawdzania tabel podczas debugowania pakietu.
W SQL Server Manager Studio możesz przetestować kod T-SQL, zawijając go w transakcji, aby dać Ci możliwość wycofania zmian. Na przykład w testowej bazie danych możesz chcieć przywrócić dane do stanu początkowego w ramach testu. Jeśli testujesz kod zawarty w transakcji i chcesz sprawdzić zablokowane tabele podczas trwania transakcji, możesz użyć USTAW POZIOMU IZOLACJI ODCZYTAJ NIEZGODNIE, aby sprawdzić wartości w innym oknie.
Przyjmuję do wiadomości, że są to dość niejasne zastosowania dla CZYTAJ NIEZGODNE, ale uważam je za przydatne w środowisku testowym.
źródło
W większości baz danych zdecydowana większość działań, nawet wstawianie, usuwanie i aktualizacje, nie obejmuje jawnych transakcji.
Jasne,
READ UNCOMMITTED
(Brudne odczyty) mogą w takich przypadkach podawać nieprawidłowe informacje, ale te informacje BYŁY prawidłowe 5 sekund wcześniej.Czasy, w których Dirty Reads przynoszą naprawdę złe wyniki, mają miejsce, gdy transakcja kończy się niepowodzeniem i musi zostać wycofana lub podczas uruchamiania zapytania w stosunku do dwóch tabel, które są zwykle aktualizowane razem przy użyciu jawnej transakcji.
Tymczasem w typowej dużej, zajętej bazie danych, która ma stosunek odczytów do zapisów od 100 (lub więcej) do 1, KAŻDE pojedyncze zapytanie (odczyt), które nie korzysta z Dirty Reads, spowalnia system, ponieważ musi uzyskać i sprawdzić dla blokad ORAZ sprawia, że znacznie bardziej prawdopodobne jest, że transakcje zakończą się niepowodzeniem (zazwyczaj z powodu zakleszczeń), co może powodować poważniejsze problemy z integralnością bazy danych.
Zamiast tego użycie brudnych odczytów sprawia, że system DUŻO jest szybszy i bardziej niezawodny (częściowo ze względu na lepszą wydajność, co zmniejsza prawdopodobieństwo wystąpienia niespójności).
Jasne, są chwile, kiedy nie należy ich używać. Nie podoba mi się ustawianie domyślnej bazy danych na używanie
READ UNCOMMITTED
poziomu izolacji, a nawet używanie jawnejSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
instrukcji na początku skryptów SQL i SP - istnieje zbyt duża szansa, że nastąpi Brudne Odczyt, gdy nie powinno. Zamiast tego(NOLOCK)
podpowiedzi są znacznie lepszym podejściem, ponieważ wyraźnie wskazują, że programista pomyślał o tym, co robią i zdecydował, że dla tej konkretnej tabeli w tym zapytaniu Dirty Reads są bezpieczne.Jeśli programujesz aplikację do przesyłania pieniędzy z jednego konta bankowego na inne, nie powinieneś używać Dirty Reads. Ale większość aplikacji nie potrzebuje takiego poziomu paranoi.
źródło