2009-03-19 12 views
32

Cała dokumentacja dotycząca zakleszczeń SQL Server 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 AZakleszczenia SQL Server między wybieraniem/aktualizacją lub wieloma wyborami

Jednak często widzę zakleszczenia między wyborem i aktualizacją, a nawet między wieloma wyborami w niektórych z naszych zajętych aplikacji. Uważam, że niektóre z lepszych wyników śledzenia impasu są całkiem nieprzeniknione, ale chciałbym po prostu zrozumieć, co może spowodować impas między dwiema pojedynczymi operacjami. Na pewno, jeśli opcja select ma blokadę odczytu, aktualizacja powinna po prostu poczekać przed uzyskaniem wyłącznej blokady i na odwrót?

To dzieje się na SQL Server 2005, nie sądzę, że to robi różnicę.

Odpowiedz

11

kiedyś zakładka 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.

0

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

+0

Rozumiem o poziomach izolacji, powyższe zakleszczenia można rozwiązać, powodując, że wybrana opcja read uncommitted BUT, ale dlaczego odczyt, który rozpoczyna się ZANIM aktualizacja kończy się impasem z tą aktualizacją przy użyciu read? –

1

Poprawne odczytywanie na transakcjach i poziomach izolacji: w przypadku dość gęstej, ale dość dokładnej i neutralnej technologicznie pracy, patrz Principles of Transaction Processing. To wstrząsnęło moim światem (i dał mi sporo bóle głowy!).

Nie jestem pewien, z czym masz problemy, ani z jakiego poziomu izolacji korzystasz. Ale pomyśl o tym: ponieważ silnik bazy danych wie, że jeśli czytasz w jednej transakcji, w jaki sposób może on stwierdzić, czy zamierzasz pisać później? Wysokie poziomy izolacji wymagają blokowania za każdym razem, gdy wykonywany jest odczyt, ewentualnie na całej tabeli w celu ochrony przed odczytami fantomowymi, ponieważ dane mogą wpłynąć na późniejsze zapisanie.

Czy chcesz, aby baza danych długo czekać na wyłączne blokowanie danych? Przyjrzyj się swoim poziomom izolacji przez cały czas i czy niepotrzebnie uruchamiasz serię odczytów jako odosobnioną transakcję. Nie zawsze łatwo jest określić, jak brudne odczyty można tolerować, choć ...

+2

Wydaje mi się, że pytanie o plakaty było bardziej szczegółowe niż ogólne przekonanie, że poziom izolacji może się uleczyć. – eckes

+0

Nie będę dokładnie charakteryzował PoTP jako rantu. Rob specjalnie poprosił o pomoc w zrozumieniu transakcji i wydawał się mieć problem ze zrozumieniem związanych z tym kompromisów. Jeśli wskazywanie przydatnej literatury jest rantowaniem, to prawdopodobnie cały czas piję na ustach! YMMV. –

5

Zamki między pojedynczych zapytań może się zdarzyć, jak zablokować ich pojedynczych wierszy, nie całą tabelę:

Zapytanie aktualizacja pobiera aktualizacji blokady kilka wierszy w tabeli, a zapytanie wyboru pobiera blokadę odczytu w niektórych innych wierszach tabeli. Zapytanie o aktualizację następnie próbuje uzyskać blokadę aktualizacji wierszy, które są odczytywane jako zablokowane, a zapytanie wyboru próbuje uzyskać blokadę odczytu wierszy, które są blokowane.

Może to jeszcze bardziej skomplikować blokady eskalacji, tzn. Baza danych decyduje o tym, że zbyt wiele pojedynczych wierszy jest zablokowanych przez transakcję, tak że powinna zostać eskalowana do zablokowania sekcji tabeli lub całej tabeli. Oznacza to, że blokada może wpływać na wiersze, które nie są bezpośrednio związane z zapytaniem.

19

Może się tak zdarzyć, ponieważ selektor blokuje dwa różne indeksy, tymczasem aktualizacja blokuje te same indeksy w odwrotnej kolejności. Wybór wymaga dwóch indeksów, ponieważ pierwszy indeks nie obejmuje wszystkich kolumn, do których musi uzyskać dostęp; aktualizacja wymaga dwóch indeksów, ponieważ jeśli zaktualizujesz kluczową kolumnę indeksu, musisz ją zablokować.

http://blogs.msdn.com/bartd/archive/2006/09/25/770928.aspx ma fantastyczne wytłumaczenie. Sugerowane poprawki obejmują dodanie indeksu obejmującego wszystkie kolumny wymagane przez wybrane, przejście do izolacji migawki lub wyraźne wymuszenie wybrania, aby pobrać blokadę aktualizacji, której normalnie nie potrzebuje.

12

Jestem zaskoczony, nikt nie wspomniał o podpowiedzi blokowania WITH (UPDLOCK). Jest to bardzo przydatne, jeśli masz zakleszczenia obejmujące np. dwie pary wkładek selektywnych pracujące równolegle.

W przypadku serwera SQL, jeśli wybiorą Państwo z WITH (UPDLOCK), drugie wybieranie będzie czekać do zakończenia pierwszego wyboru. W przeciwnym razie otrzymają udostępnione blokady, a gdy jednocześnie spróbują dokonać aktualizacji do wyłącznych blokad, zostaną zablokowane.

+0

'Rolf Kristensen' wyjaśnił' WITH (UPDLOCK) 'doskonale w swojej odpowiedzi. – Mahmoodvcs

4

Domyślam się, że instrukcja select nabywa blokadę odczytu, gdy otrzymasz instrukcję update, wówczas musi zostać zaktualizowana do blokady zapisu.

Aktualizacja do blokady zapisu wymaga, aby wszystkie inne blokady do odczytu zostały usunięte (ich transakcje wybierania są zakończone). Ale jeśli inny proces ma już genialny pomysł na uaktualnienie do blokady zapisu, nagle masz dwa procesy, które czekają na siebie, aby zwolnić blokadę odczytu, aby mogły uzyskać blokadę zapisu.

Jeśli korzystasz z opcji select-for-update (UPDLOCK), to od początku będzie blokować blokadę zapisu, a następnie nie wystąpi problem z zakleszczeniem.