Blokady SQL Server między select/update lub wieloma selekcjami

Cała dokumentacja na SQL Server deadlocks mówi o scenariuszu, w którym operacja 1 blokuje zasób A, a następnie próbuje uzyskać dostęp do zasobu B, a operacja 2 blokuje zasób B i próbuje uzyskać dostęp do zasobu A.

Jednak dość często widzę blokady pomiędzy select I update, a nawet między wieloma selekcjami w niektórych naszych ruchliwych aplikacjach. Uważam, że niektóre z drobniejszych punktów impasu trace output są dość nieprzeniknione, ale naprawdę chciałbym zrozumieć, co może spowodować impas między dwoma pojedynczymi operacjami. Z pewnością jeśli select ma blokadę odczytu, aktualizacja powinna poczekać przed uzyskaniem wyłącznej blokady i odwrotnie?

To się dzieje na SQL Server 2005 nie, że myślę, że to robi różnicę.

Author: Rob West, 2009-03-19

7 answers

Kiedyś dodałem dobry artykuł o Advanced SQL Server locking w SQL-Server-Performance.com. ten artykuł wykracza poza klasyczną sytuację impasu, o której wspomniałeś i może dać ci wgląd w twój problem.

 11
Author: MicSim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-27 08:20:25

Może się to zdarzyć, ponieważ select blokuje dwa różne indeksy, podczas gdy aktualizacja blokuje te same indeksy w odwrotnej kolejności. Select potrzebuje dwóch indeksów, ponieważ pierwszy indeks nie obejmuje wszystkich kolumn, do których ma dostęp; aktualizacja potrzebuje dwóch indeksów, ponieważ jeśli zaktualizujesz kolumnę klucza indeksu, musisz ją zablokować.

Http://blogs.msdn.com/bartd/archive/2006/09/25/770928.aspx ma fantastyczne Wyjaśnienie. Zasugerował poprawki obejmują dodanie indeksu obejmującego wszystkie kolumny, których select potrzebuje, przełączenie na izolację migawek lub jawne zmuszenie select do przechwycenia blokady aktualizacji, której normalnie nie potrzebuje.

 19
Author: David Eison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-25 14:08:40

Dziwi mnie, że nikt nie wspomniał o podpowiedzi o blokowaniu. Jest to bardzo przydatne, jeśli masz blokady obejmujące np. dwie pary select-insert działające równolegle.

W SQL Server, jeśli wystawisz Select z WITH (UPDLOCK), drugie select będzie czekać, aż pierwsze select zostanie zakończone. W przeciwnym razie dostają współdzielone zamki, a gdy jednocześnie próbują uaktualnić do ekskluzywnych zamków, blokują się.

 12
Author: Ben Challenor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-07 22:57:53

Blokady między pojedynczymi zapytaniami mogą się zdarzyć, ponieważ blokują pojedyncze wiersze, a nie całą tabelę:

Zapytanie o aktualizację otrzymuje blokadę aktualizacji dla kilku wierszy w tabeli, a Zapytanie o select otrzymuje blokadę odczytu dla niektórych innych wierszy w tabeli. Zapytanie aktualizacyjne próbuje uzyskać blokadę aktualizacji w wierszach, które są zablokowane do odczytu, a zapytanie select próbuje uzyskać blokadę odczytu w wierszach, które są zablokowane do odczytu.

Może się jeszcze bardziej skomplikować z blokadami eskalacyjnymi, tzn. baza danych decyduje że istnieje zbyt wiele pojedynczych wierszy zablokowanych przez transakcję, więc należy ją eskalować do zablokowania sekcji tabeli lub całej tabeli. Oznacza to, że blokada może mieć wpływ na wiersze, które nie są bezpośrednio zaangażowane w Zapytanie.

 5
Author: Guffa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-19 12:29:35

Domyślam się, że instrukcja select wymaga blokady odczytu, gdy pojawi się instrukcja update, to musi zostać uaktualniona do blokady zapisu.

Uaktualnienie do blokady zapisu wymaga usunięcia wszystkich innych blokad odczytu (ich transakcje select zostaną zakończone). Ale jeśli inny proces ma już genialny pomysł, aby uaktualnić do blokady zapisu, nagle masz dwa procesy czekające na siebie, aby zwolnić blokadę odczytu, aby mogli uzyskać blokadę zapisu.

Jeśli używasz select-for-update (UPDLOCK) następnie uzyska blokadę zapisu Od początku, a następnie nie masz problemu z blokadą.

 4
Author: Rolf Kristensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-18 12:00:02

Przeczytaj poprawnie o transakcjach i poziomach izolacji: aby uzyskać nieco gęstą, ale dość dokładną i neutralną technologicznie pracę, zobacz Zasady przetwarzania transakcji. To wstrząsnęło moim światem (i dał mi sporo bólu głowy!).

Nie wiem z czym masz problem, ani z jakim poziomem izolacji używasz. Ale rozważ to: dla wszystkich silnik bazy danych wie, jeśli nie czyta w jednej transakcji, jak to powiedzieć, czy masz zamiar zrobić zapis później? Wysoki poziom izolacji wymaga blokowania podczas odczytu, ewentualnie na całej tabeli w celu ochrony przed odczytem fantomowym, ponieważ dane mogą mieć wpływ na późniejszy zapis.

Czy chcesz, aby baza danych czekała arbitralnie długo na wyłączną blokadę Twoich danych? Przyjrzyj się poziomom izolacji i czy niepotrzebnie uruchamiasz serię odczytów jako izolowaną transakcję. Jednak nie zawsze łatwo jest określić, jak brudne czyta można tolerować...

 1
Author: Pontus Gagge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-19 12:16:00

Powinieneś poczytać o izolacji transakcji: http://msdn.microsoft.com/en-us/library/ms173763.aspx

 0
Author: James L,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-19 11:52:17