Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Zdezorientowany UPDLOCK, HOLDLOCK

Dlaczego UPDLOCK miałby wybierać bloki? Macierz zgodności zamków wyraźnie pokazuje N dla rywalizacji S/U i USA, jak w Brak konfliktu .

Jeśli chodzi o wskazówkę HOLDLOCK, dokumentacja stwierdza:

HOLDLOCK:jest odpowiednikiem opcji SERIALIZABLE. Aby uzyskać więcej informacji, zobacz SERIALIZABLE w dalszej części tego tematu.

...

SERIALIZABLE:... skanowanie jest wykonywane z taką samą semantyką jak transakcja działająca na poziomie izolacji SERIALIZABLE...

a temat Poziom izolacji transakcji wyjaśnia, co oznacza SERIALIZABLE:

Żadne inne transakcje nie mogą modyfikować danych, które zostały odczytane przez bieżącą transakcję, dopóki bieżąca transakcja się nie zakończy.

Inne transakcje nie mogą wstawiać nowych wierszy z wartościami kluczy, które mieszczą się w zakresie kluczy odczytywanych przez jakiekolwiek instrukcje w bieżącej transakcji, dopóki bieżąca transakcja nie zostanie zakończona.

Dlatego widoczne zachowanie jest doskonale wyjaśnione w dokumentacji produktu:

  • UPDLOCK nie blokuje jednoczesnych operacji SELECT ani INSERT, ale blokuje UPDATE lub DELETE wierszy wybranych przez T1
  • HOLDLOCK oznacza SERALIZOWALNY i dlatego umożliwia WYBIERANIE, ale blokuje UPDATE i DELETE wierszy wybranych przez T1, również jako dowolna INSERT w zakresie wybranym przez T1 (czyli cała tabela, zatem dowolna wstaw).
  • (UPDLOCK, HOLDLOCK):Twój eksperyment nie pokazuje, co zostałoby zablokowane poza powyższym przypadkiem, a mianowicie inną transakcją z UPDLOCK w T2 :
    SELECT * FROM dbo.Test WITH (UPDLOCK) WHERE ...
  • TABLOCKX nie ma potrzeby wyjaśniania

Prawdziwe pytanie brzmi:co chcesz osiągnąć ? Zabawa z podpowiedziami blokowania bez absolutnego pełnego 110% zrozumienia semantyki blokowania to błaganie o kłopoty...

Po edycji OP:

Chciałbym wybrać wiersze z tabeli i uniemożliwić modyfikację danych w tej tabeli podczas ich przetwarzania.

Powinieneś użyć jednego z wyższych poziomów izolacji transakcji. ODCZYT POWTARZALNY uniemożliwi modyfikację odczytanych danych. SERIALIZABLE zapobiegnie modyfikowaniu odczytanych danych i nowe dane przed wstawieniem. Korzystanie z poziomów izolacji transakcji jest właściwym podejściem, w przeciwieństwie do korzystania ze wskazówek dotyczących zapytań. Kendra Little ma ładny plakat wyjaśniający poziomy izolacji.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. DATETIMEOFFSETFROMPARTS() Przykłady w SQL Server (T-SQL)

  2. Tabela historii programu SQL Server — wypełnianie za pomocą SP lub wyzwalacza?

  3. Przekroczenie limitu czasu zapytania po wykonaniu z sieci, ale superszybkie po wykonaniu z SSMS

  4. Błąd zapytania z niejednoznaczną nazwą kolumny w SQL

  5. Skopiuj tabelę do innej bazy danych na innym serwerze SQL