Korzystam z programu SQL Server 2005 Express.
W scenariuszu dodałem Begin Transaction
polecenie tuż przed INSERT
instrukcją w procedurze składowanej. Kiedy wykonałem tę procedurę przechowywaną, zablokowałem całą tabelę, a wszystkie jednoczesne połączenia pokazywały zawieszony ekran do czasu INSERT
zakończenia.
Dlaczego cała tabela jest blokowana i jak rozwiązać ten problem w SQL Server 2005 Express?
Edytowane
Zapytanie jest jak poniżej:
INSERT INTO <table2> SELECT * FROM <table1> WHERE table1.workCompleted = 'NO'
Odpowiedzi:
Ta odpowiedź może okazać się pomocna w stosunku do pierwotnego pytania, ale ma przede wszystkim dotyczyć niedokładnych informacji w innych postach. Podkreśla także część nonsensów w BOL.
Połączona sekcja BOL stwierdza:
Uwaga: W dniu 2014–8–27 BOL został zaktualizowany w celu usunięcia niepoprawnych stwierdzeń cytowanych powyżej.
Na szczęście tak nie jest. Gdyby tak było, wstawianie do tabeli występowałoby szeregowo, a wszystkie czytniki byłyby blokowane z całej tabeli, dopóki transakcja wstawiania nie zostanie zakończona. Dzięki temu SQL Server byłby tak samo wydajnym serwerem bazy danych jak NTFS. Nie bardzo.
Zdrowy rozsądek sugeruje, że tak nie może być, ale jak zauważa Paul Randall: „ Zrób sobie przysługę, nie ufaj nikomu ”. Jeśli nie możesz ufać nikomu, w tym BOL , chyba będziemy musieli to udowodnić.
Utwórz bazę danych i wypełnij tabelę zastępczą wiązką wierszy, zwracając uwagę, że zwrócono DatabaseId.
Skonfiguruj śledzenie profilera, które będzie śledzić blokadę: uzyskane i blokowanie: zwolnione zdarzenia, filtrowanie na DatabaseId z poprzedniego skryptu, ustawienie ścieżki do pliku i odnotowanie zwrócenia TraceId.
Wstaw wiersz i zatrzymaj śledzenie:
Otwórz plik śledzenia, a znajdziesz następujące informacje:
Sekwencja wykonanych blokad jest następująca:
Blokady są następnie zwalniane w odwrotnej kolejności. W żadnym momencie nie uzyskano wyłącznego zamka na stole.
Tak to jest. SQL Server (i prawdopodobnie dowolny silnik relacyjnej bazy danych) nie ma przewidywania, jakie inne partie mogą być uruchomione podczas przetwarzania instrukcji i / lub partii, więc sekwencja pozyskiwania blokady nie jest różna.
W tym konkretnym przykładzie przyjmowane są dokładnie takie same blokady. Nie ufaj mi, spróbuj!
źródło
Nie wykonuję dużo pracy w języku T-SQL, ale czytam dokumentację
Jest to zgodne z projektem, jak stwierdzono w POCZĄTKU TRANSAKCJI :
I jak stwierdzono w dokumentacji INSERT , uzyska on wyłączną blokadę na stole. Jedynym sposobem, w jaki można wykonać SELECT względem tabeli, jest użycie
NOLOCK
lub ustawienie poziomu izolacji transakcji.źródło