Mam proces z Select, który zajmuje dużo czasu, w kolejności od 5 do 10 minut.
Obecnie nie używam NOLOCK jako wskazówki do silnika bazy danych MS SQL.
W tym samym czasie mamy inny proces, który dokonuje aktualizacji i wstawia do tej samej bazy danych i tych samych tabel.
Rozpoczął się pierwszy proces, który niedawno zakończył się przedwcześnie przekazem wiadomości
SQLEXCEPTION: transakcja została zablokowana na zasobach blokady z innym procesem i została wybrana jako ofiara zakleszczenia.
Ten pierwszy proces przebiega w innych witrynach w identycznych warunkach, ale z mniejszymi bazami danych, a zatem omawiana instrukcja select zajmuje znacznie krótszy okres czasu (rzędu około 30 sekund). W innych witrynach nie widzę komunikatu o zakleszczeniu w innych witrynach. Również nie dostałem tego komunikatu na stronie, na której początkowo występuje problem, ale zakładam, że wraz z rozrostem bazy danych, wydaje mi się, że przekroczyłem jakiś próg. Oto moje pytania:
- Czy czas potrzebny na wykonanie transakcji może zwiększyć prawdopodobieństwo, że powiązany proces zostanie oflagowany jako ofiara zakleszczenia?
- Jeśli wykonam selekcję ze wskazówką NOLOCK, czy spowoduje to usunięcie problemu?
- Podejrzewam, że pole datetime, które jest sprawdzane jako część klauzuli WHERE w instrukcji select, powoduje powolny czas wyszukiwania. Czy mogę utworzyć indeks na podstawie tego pola? Czy to jest wskazane?
źródło
Odpowiedzi:
Nie. SELECT jest ofiarą, ponieważ miał tylko odczytane dane, dlatego transakcja wiąże się z niższym kosztem , więc zostaje wybrana jako ofiara:
Nie. Z kilku powodów:
Prawdopodobnie. Przyczyną zakleszczenia jest prawie bardzo prawdopodobne, że baza danych jest słabo zindeksowana. 10 minut zapytań jest akceptowalnych w tak wąskich warunkach, że jestem w 100% pewien, że w twoim przypadku jest to nie do przyjęcia.
Z 99% pewnością oświadczam, że zakleszczenie jest spowodowane dużym skanowaniem tabeli, które powoduje konflikt z aktualizacjami. Zacznij od uchwycenia wykresu zakleszczenia, aby przeanalizować przyczynę. Najprawdopodobniej będziesz musiał zoptymalizować schemat swojej bazy danych. Przed wprowadzeniem jakichkolwiek modyfikacji przeczytaj ten temat Projektowanie indeksów i artykuły podrzędne.
źródło
Oto, w jaki sposób ten konkretny problem z zakleszczeniem faktycznie wystąpił i jak został faktycznie rozwiązany. Jest to dość aktywna baza danych, w której codziennie występuje 130 tys. Transakcji. Indeksy w tabelach w tej bazie danych były pierwotnie zgrupowane. Klient zażądał, aby indeksy nie były klastrowane. Tak szybko, jak to zrobiliśmy, rozpoczął się impas. Kiedy ponownie ustanowiliśmy indeksy jako klastrowe, impas ustał.
źródło
Warto spróbować odpowiedzi, ale powinieneś także przejrzeć swój kod. W szczególności przeczytaj odpowiedź Polyfuna: Jak pozbyć się zakleszczenia w SQL Server 2005 i aplikacji C #?
Wyjaśnia problem współbieżności i jak użycie "with (updlock)" w zapytaniach może poprawić sytuację zakleszczenia - w zależności od tego, co dokładnie robi twój kod. Jeśli twój kod jest zgodny z tym wzorcem, jest to prawdopodobnie lepsze rozwiązanie przed uciekaniem się do brudnych odczytów itp.
źródło
Chociaż @ Remus Ruşanu „s jest już odpowiedź doskonała, w jednym przypadku oczekuje lepszy wgląd w SQL Server Deadlock przyczyn i strategie śladowe, proponuję czytać Brad McGehee ” s Jak wyśledzić zakleszczenia przy użyciu programu SQL Server 2005 Profiler
źródło