Zoptymalizowane blokowanie
Dotyczy:Azure SQL Database
bazy danych SQL w Microsoft Fabric
W tym artykule przedstawiono zoptymalizowane blokowanie, funkcję aparatu bazy danych, która oferuje ulepszony mechanizm zamków transakcyjnych w celu zmniejszenia zużycia pamięci blokady oraz ograniczenia blokad dla współbieżnych transakcji.
Co to jest zoptymalizowane blokowanie?
Zoptymalizowane blokowanie pomaga zmniejszyć ilość pamięci blokady, ponieważ bardzo mało blokad jest przechowywanych nawet w przypadku dużych transakcji. Ponadto zoptymalizowane blokowanie pozwala również uniknąć eskalacji blokady. Umożliwia to bardziej współbieżny dostęp do tabeli.
Zoptymalizowane blokowanie składa się z dwóch podstawowych składników: blokady identyfikatora transakcji (TID) i blokowania po kwalifikacji (LAQ).
- Identyfikator transakcji (TID) jest unikatowym identyfikatorem transakcji. Każdy wiersz ma oznaczenie z ostatnim TID, który go zmodyfikował. Zamiast potencjalnie wielu blokad klucza lub identyfikatora wiersza, używana jest pojedyncza blokada TID. Aby uzyskać więcej informacji, zobacz Transaction ID (TID) locking.
- Blokada po kwalifikacjach (LAQ) to optymalizacja, która ocenia predykaty zapytań przy użyciu najnowszej zatwierdzonej wersji wiersza bez uzyskiwania blokady, co poprawia współbieżność. Aby uzyskać więcej informacji, zobacz Lock after qualification (LAQ).
Na przykład:
- Bez zoptymalizowanego blokowania aktualizowanie 1000 wierszy w tabeli może wymagać 1000 wyłącznych (
X
) blokad wierszy przechowywanych do końca transakcji. - W przypadku zoptymalizowanego blokowania aktualizowanie 1000 wierszy w tabeli może wymagać 1000
X
blokad wierszy, ale każda z nich jest zwalniana natychmiast po zaktualizowaniu każdego wiersza, a tylko jedna blokada TID jest utrzymywana do końca transakcji. Ponieważ blokady są szybko zwalniane, użycie pamięci blokady jest zmniejszane, a eskalacji blokady jest znacznie mniej prawdopodobne, co zwiększa współbieżność obciążenia.
Notatka
Włączenie zoptymalizowanego blokowania zmniejsza lub eliminuje blokady wierszy i stron uzyskanych przez instrukcje języka DML (Data Modification Language), takie jak INSERT
, UPDATE
, DELETE
, MERGE
. Nie ma wpływu na inne rodzaje blokad bazy danych i obiektów, takie jak blokady schematu.
Dostępność
Zoptymalizowane blokowanie jest dostępne tylko w usłudze Azure SQL Database i SQL Database w usłudze Microsoft Fabric tylko we wszystkich warstwach usług i rozmiarach obliczeniowych.
Zoptymalizowane blokowanie nie jest obecnie dostępne w usłudze Azure SQL Managed Instance ani w programie SQL Server.
Czy jest włączone zoptymalizowane blokowanie?
Zoptymalizowane blokowanie jest włączone dla bazy danych użytkowników. Połącz się z bazą danych, a następnie użyj następującego zapytania, aby sprawdzić, czy jest włączona zoptymalizowana blokada:
SELECT IsOptimizedLockingOn = DATABASEPROPERTYEX(DB_NAME(), 'IsOptimizedLockingOn');
Wynik | Opis |
---|---|
0 |
Zoptymalizowane blokowanie jest wyłączone. |
1 |
Zoptymalizowane blokowanie jest włączone. |
NULL |
Zoptymalizowane blokowanie nie jest dostępne. |
Zoptymalizowane blokowanie opiera się na innych funkcjach bazy danych:
- Zoptymalizowane blokowanie wymaga włączenia przyspieszonego odzyskiwania bazy danych (ADR) w bazie danych.
- Aby uzyskać największą korzyść z zoptymalizowanego blokowania, należy włączyć izolację migawkową z zatwierdzaniem do odczytu (RCSI) dla bazy danych. Składnik LAQ zoptymalizowanego blokowania jest skuteczny tylko wtedy, gdy funkcja RCSI jest włączona.
Zarówno adr, jak i RCSI są domyślnie włączone w usłudze Azure SQL Database. Aby sprawdzić, czy te opcje są włączone dla bieżącej bazy danych, połącz się z bazą danych i uruchom następujące zapytanie T-SQL:
SELECT name,
is_read_committed_snapshot_on,
is_accelerated_database_recovery_on
FROM sys.databases
WHERE name = DB_NAME();
Omówienie blokowania
Jest to krótkie podsumowanie zachowania, gdy zoptymalizowane blokowanie nie jest włączone. Aby uzyskać więcej informacji, zapoznaj się z przewodnikiem Transaction locking and row versioning (Blokowanie transakcji i przechowywanie wersji wierszy).
W aparacie bazy danych blokowanie jest mechanizmem uniemożliwiającym jednoczesne aktualizowanie tych samych danych przez wiele transakcji w celu zagwarantowania ACID właściwości transakcji.
Gdy transakcja musi zmodyfikować dane, żąda blokady danych. Blokada jest przyznawana, jeśli na danych nie są utrzymywane żadne inne blokady powodujące konflikt, a transakcja może przystąpić do modyfikacji. Jeśli na danych jest przechowywana inna blokada powodująca konflikt, transakcja musi poczekać na zwolnienie blokady, zanim będzie mogła kontynuować.
Gdy wiele transakcji próbuje uzyskać dostęp do tych samych danych jednocześnie, aparat bazy danych musi rozwiązać potencjalnie złożone konflikty z równoczesnymi operacjami odczytu i zapisu. Blokowanie jest jednym z mechanizmów, za pomocą których silnik może zapewnić semantykę transakcji ANSI SQL poziomów izolacji. Chociaż blokowanie w bazach danych jest niezbędne, to zmniejszona współbieżność, zakleszczenia, złożoność i narzut związany z blokadami mogą wpływać na wydajność i skalowalność.
Blokowanie identyfikatora transakcji (TID)
Kiedy używane są poziomy izolacji oparte na wersjonowaniu wierszy lub gdy ADR jest włączone, każdy wiersz w bazie danych wewnętrznie zawiera identyfikator transakcji (TID). Ten identyfikator TID jest utrwalany na dysku. Każda transakcja modyfikująca wiersz oznacza ten wiersz swoim identyfikatorem TID.
W przypadku blokowania TID, zamiast zakładania blokady na kluczu wiersza, blokada jest zakładana na TID wiersza. Transakcja modyfikująca przechowuje blokadę X
na TID. Inne transakcje uzyskują blokadę S
na TID, aby poczekać na ukończenie pierwszej transakcji. Dzięki blokadzie TID, blokady stron i wierszy są nadal stosowane podczas modyfikacji, ale każda z tych blokad jest zwalniana natychmiast po dokonaniu modyfikacji wiersza. Jedyną blokadą przechowywaną do końca transakcji jest blokada X
zasobu TID, która zastępuje wiele blokad strony i wiersza (klucza).
Rozważmy następujący przykład pokazujący blokady dla bieżącej sesji, gdy transakcja zapisu jest aktywna:
/* Is optimized locking is enabled? */
SELECT IsOptimizedLockingOn = DATABASEPROPERTYEX(DB_NAME(), 'IsOptimizedLockingOn');
CREATE TABLE t0
(
a int PRIMARY KEY,
b int NULL
);
INSERT INTO t0 VALUES (1,10),(2,20),(3,30);
GO
BEGIN TRANSACTION;
UPDATE t0
SET b = b + 10;
SELECT *
FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID
AND
resource_type IN ('PAGE','RID','KEY','XACT');
COMMIT TRANSACTION;
GO
DROP TABLE IF EXISTS t0;
Jeśli włączono zoptymalizowane blokowanie, żądanie przechowuje tylko jedną blokadę X
w zasobie XACT
(transakcja).
Jeśli zoptymalizowane blokowanie nie jest włączone, to samo żądanie zawiera cztery blokady — jedną blokadę IX
(wyłączność intencji) na stronie zawierającej wiersze, a trzy X
blokady kluczy w każdym wierszu:
Dynamiczny widok zarządzania (DMV) sys.dm_tran_locks jest przydatny podczas badania lub rozwiązywania problemów z blokowaniem, takich jak obserwowanie zoptymalizowanego blokowania w działaniu.
Blokada po kwalifikacjach (LAQ)
Opierając się na infrastrukturze TID, zoptymalizowane blokowanie zmienia sposób, w jaki instrukcje DML, takie jak INSERT
, UPDATE
i DELETE
uzyskują blokady.
Bez zoptymalizowanego blokowania, predykaty zapytań są sprawdzane wiersz po wierszu podczas skanowania, najpierw aktualizując blokadę wiersza (U
). Jeśli predykat jest spełniony, zostanie założona blokada wiersza na wyłączność (X
) przed zaktualizowaniem wiersza i utrzymywana do końca transakcji.
Po włączeniu zoptymalizowanego blokowania oraz poziomu izolacji migawek READ COMMITTED
(RCSI), predykaty mogą być weryfikowane optymistycznie na najnowszej zatwierdzonej wersji wiersza bez konieczności zakładania jakichkolwiek blokad. Jeśli predykat nie spełnia wymagań, zapytanie zostanie przeniesione do następnego wiersza w skanowaniu. Jeśli predykat jest spełniony, zostanie podjęta blokada wiersza X
celem zaktualizowania wiersza.
Innymi słowy, blokada jest wykonywana po kwalifikacji wiersza na do modyfikacji. Blokada wiersza X
jest zwalniana natychmiast po zakończeniu aktualizacji wiersza, zanim transakcja zostanie zakończona.
Ponieważ ocena predykatu jest wykonywana bez uzyskiwania żadnych blokad, współbieżne zapytania modyfikujące różne wiersze nie blokują się nawzajem.
Na przykład:
CREATE TABLE t1
(
a int NOT NULL,
b int NULL
);
INSERT INTO t1
VALUES (1,10),(2,20),(3,30);
GO
Sesja 1 | Sesja 2 |
---|---|
BEGIN TRANSACTION; UPDATE t1 SET b = b + 10 WHERE a = 1; |
|
BEGIN TRANSACTION; UPDATE t1 SET b = b + 10 WHERE a = 2; |
|
COMMIT TRANSACTION; |
|
COMMIT TRANSACTION; |
Bez zoptymalizowanego blokowania sesja 2 jest blokowana, ponieważ sesja 1 trzyma blokadę U
na wierszu, który sesja 2 musi zaktualizować. Jednak w przypadku zoptymalizowanego blokowania sesja 2 nie jest blokowana, ponieważ blokady U
nie są wykonywane, a ponieważ w najnowszej zatwierdzonej wersji wiersza 1 kolumna a
równa się 1, co nie spełnia predykatu sesji 2.
LAQ jest wykonywane optymistycznie na założeniu, że wiersz nie jest modyfikowany po sprawdzeniu predykatu. Jeśli predykat jest spełniony, a wiersz nie został zmodyfikowany po sprawdzeniu predykatu, wiersz jest modyfikowany przez bieżącą transakcję.
Ponieważ blokady U
nie są wykonywane, współbieżna transakcja może zmodyfikować wiersz po ocenie predykatu. Jeśli w wierszu znajduje się aktywna transakcja zawierająca blokadę X
TID, aparat bazy danych czeka na jego zakończenie. Jeśli wiersz uległ zmianie po wcześniejszym obliczeniu predykatu, aparat bazy danych ponownie ocenia (ponownie kwalifikuje) predykat ponownie przed zmodyfikowaniem wiersza. Jeśli predykat jest nadal spełniony, wiersz zostanie zmodyfikowany.
Ponowne kwalifikowanie predykatów jest obsługiwane przez podzbiór operatorów silnika zapytań. Jeśli wymagana jest ponowna ocena predykatu, ale plan zapytania używa operatora, który nie obsługuje ponownej kwalifikacji predykatu, silnik bazy danych wewnętrznie przerywa przetwarzanie instrukcji i uruchamia je ponownie bez LAQ. Gdy wystąpi takie anulowanie, zdarzenie rozszerzone lock_after_qual_stmt_abort
zostanie wyzwolone.
Niektóre instrukcje, na przykład instrukcje UPDATE
ze zmiennym przypisaniem i instrukcjami z klauzulą OUTPUT, nie mogą zostać przerwane i ponownie uruchomione bez zmiany ich semantyki. W przypadku takich stwierdzeń LAQ nie jest używany.
W poniższym przykładzie predykat jest ponownie oceniany, ponieważ kolejna transakcja zmieniła wiersz:
CREATE TABLE t3
(
a int NOT NULL,
b int NULL
);
INSERT INTO t3 VALUES (1,10),(2,20),(3,30);
GO
Sesja 1 | Sesja 2 |
---|---|
BEGIN TRANSACTION; UPDATE t3 SET b = b + 10 WHERE a = 1; |
|
BEGIN TRANSACTION; UPDATE t3 SET b = b + 10 WHERE a = 1; |
|
COMMIT TRANSACTION; |
|
COMMIT TRANSACTION; |
Heurystyka LAQ
Zgodnie z opisem w Lock after qualification (LAQ), gdy jest używana LAQ, niektóre instrukcje mogą być ponownie uruchamiane i przetwarzane wewnętrznie bez udziału LAQ. Jeśli dzieje się to często, obciążenie związane z powtarzającym się przetwarzaniem może stać się znaczące. Aby utrzymać to obciążenie do minimum, zoptymalizowane blokowanie używa mechanizmu heurystyki do śledzenia powtarzanego przetwarzania. Ten mechanizm wyłącza funkcję LAQ dla bazy danych, jeśli obciążenie przekracza próg.
Na potrzeby mechanizmu heurystyki praca wykonywana przez instrukcję jest mierzona w liczbie przetworzonych stron (odczytów logicznych). Jeśli aparat bazy danych modyfikuje wiersz, który został zmodyfikowany przez inną transakcję po rozpoczęciu przetwarzania instrukcji, praca wykonywana przez instrukcję jest traktowana jako potencjalnie zmarnowana, ponieważ instrukcja może zostać przerwana i ponownie uruchomiona. System śledzi łączną pracę potencjalnie zmarnowaną oraz całkowitą pracę wykonywaną przez wszystkie instrukcje w bazie danych.
Funkcja LAQ jest wyłączona dla bazy danych, jeśli wartość procentowa potencjalnie zmarnowanej pracy przekroczy próg. Funkcja LAQ jest również wyłączona, gdy liczba ponownych uruchomień instrukcji przekracza próg.
Jeśli zmarnowana praca i liczba ponownie uruchomionych instrukcji spadnie poniżej odpowiednich progów, usługa LAQ zostanie ponownie włączona dla bazy danych.
Zmiany zachowania zapytań przy użyciu zoptymalizowanego blokowania i RCSI
Współbieżne obciążenia w ramach izolacji migawek zatwierdzonych do odczytu (RCSI), które opierają się na ścisłej kolejności wykonywania transakcji, mogą doświadczać różnic w zachowaniu zapytań, gdy włączone jest zoptymalizowane blokowanie.
Rozważmy następujący przykład, w którym transakcja T2 aktualizuje tabelę t4
na podstawie kolumny b
, która została zaktualizowana podczas transakcji T1.
CREATE TABLE t4
(
a int NOT NULL,
b int NULL
);
INSERT INTO t4
VALUES (1,1);
GO
Sesji 1 | Sesja 2 |
---|---|
BEGIN TRANSACTION T1; UPDATE t4 SET b = 2 WHERE a = 1; |
|
BEGIN TRANSACTION T2; UPDATE t4 SET b = 3 WHERE b = 2; |
|
COMMIT TRANSACTION; |
|
COMMIT TRANSACTION; |
Oceńmy wynik poprzedniego scenariusza z blokadą i bez blokady po kwalifikacjach (LAQ).
Bez LAQ
Bez LAQ polecenie UPDATE
w transakcji T2 jest zablokowane, czekając na zakończenie transakcji T1. Po zakończeniu T1, T2 aktualizuje kolumnę w wierszu b
na 3
, ponieważ jego warunek został spełniony.
Po zatwierdzeniu obu transakcji tabela t4
zawiera następujące wiersze:
a | b
1 | 3
z LAQ
W przypadku LAQ transakcja T2 używa najnowszej zatwierdzonej wersji wiersza, w której kolumna b
równa się 1
, w celu oceny jego predykatu (b = 2
). Wiersz nie kwalifikuje się; w związku z tym jest pomijany, a instrukcja kończy się bez blokady przez transakcję T1. W tym przykładzie LAQ usuwa blokowanie, ale prowadzi do różnych wyników.
Po zatwierdzeniu obu transakcji tabela t4
zawiera następujące wiersze:
a | b
1 | 2
Ważny
Nawet bez LAQ aplikacje nie powinny zakładać, że silnik bazy danych gwarantuje dokładne porządkowanie bez stosowania wskazówek dotyczących blokowania, gdy używane są poziomy izolacji oparte na wersjonowaniu wierszy. Naszym ogólnym zaleceniem dla klientów korzystających z współbieżnych obciążeń w wersji RCSI, które opierają się na ścisłej kolejności wykonywania transakcji (jak pokazano w poprzednim przykładzie), jest użycie bardziej rygorystycznych poziomów izolacji, takich jak REPEATABLE READ
i SERIALIZABLE
.
Dodatki diagnostyczne do zoptymalizowanego blokowania
Poniższe ulepszenia ułatwiają monitorowanie i rozwiązywanie problemów z blokowaniem i zakleszczaniem po włączeniu zoptymalizowanego blokowania:
- Typy oczekiwania na zoptymalizowane blokowanie
-
XACT
typy oczekiwańS
na blokadę na TID i opisy zasobów w sys.dm_os_wait_stats (Transact-SQL):-
LCK_M_S_XACT_READ
— występuje, gdy zadanie oczekuje na blokadę współdzieloną typuXACT
wait_resource
z zamiarem odczytu. -
LCK_M_S_XACT_MODIFY
— występuje, gdy zadanie oczekuje na wspólną blokadę typuXACT
wait_resource
z zamiarem modyfikacji. -
LCK_M_S_XACT
— występuje, gdy zadanie oczekuje na udostępnioną blokadę na typieXACT
wait_resource
, gdzie intencja nie może zostać wywnioskowana. Ten scenariusz nie jest typowy.
-
-
- Blokowanie widoczności zasobów
-
XACT
blokowanie zasobów. Aby uzyskać więcej informacji, zobaczresource_description
w sys.dm_tran_locks (Transact-SQL).
-
- Oczekiwanie na widoczność zasobu
-
XACT
oczekuje zasobów. Aby uzyskać więcej informacji, zobaczwait_resource
w sys.dm_exec_requests (Transact-SQL).
-
- Wykres zakleszczenia
- W ramach każdego zasobu w raporcie zakleszczenia
<resource-list>
, każdy element<xactlock>
raportuje podstawowe zasoby i określone informacje dotyczące blokad każdego członka zakleszczenia. Aby uzyskać więcej informacji oraz przykład, zobacz Zoptymalizowane blokowanie i zakleszczenia.
- W ramach każdego zasobu w raporcie zakleszczenia
- Zdarzenia rozszerzone
- Dochodzi do zdarzenia
lock_after_qual_stmt_abort
, gdy instrukcja zostaje wewnętrznie przerwana i zrestartowana z powodu konfliktu z inną transakcją. Aby uzyskać więcej informacji, zobacz Lock after qualification (LAQ).
- Dochodzi do zdarzenia
Najlepsze rozwiązania dotyczące zoptymalizowanego blokowania
Włączanie izolacji migawek zatwierdzonych do odczytu (RCSI)
Aby zmaksymalizować zalety zoptymalizowanego blokowania, zaleca się włączenie izolacji migawek zatwierdzonych do odczytu (RCSI) w bazie danych i używanie izolacji READ COMMITTED
jako domyślnego poziomu izolacji. Jeśli jeszcze nie włączono, włącz funkcję RCSI, łącząc się z bazą danych master
i wykonując następującą instrukcję:
ALTER DATABASE [your-database-name] SET READ_COMMITTED_SNAPSHOT ON;
W usłudze Azure SQL Database usługa RCSI jest domyślnie włączona, a READ COMMITTED
jest domyślnym poziomem izolacji. Po włączeniu wersji RCSI i w przypadku używania READ COMMITTED
poziomu izolacji czytelnicy odczytują wersję wiersza z migawki wykonanej na początku instrukcji. W przypadku LAQ pisarze kwalifikują wiersze zgodnie z predykatem na podstawie najnowszej zatwierdzonej wersji wiersza i bez uzyskiwania blokad U
. W przypadku LAQ zapytanie czeka tylko wtedy, gdy wiersz spełnia kryteria i istnieje aktywna transakcja zapisu na tym wierszu. Kwalifikowanie na podstawie najnowszej zatwierdzonej wersji i blokowanie tylko kwalifikowanych wierszy zmniejsza blokowanie i zwiększa współbieżność.
Oprócz zmniejszenia blokowania wymagana pamięć blokady jest ograniczona. Wynika to z tego, że procesy odczytu nie wykorzystują żadnych blokad, a procesy zapisu zajmują blokady na krótki czas, zamiast utrzymywać je do końca transakcji. W przypadku używania bardziej rygorystycznych poziomów izolacji, takich jak REPEATABLE READ
lub SERIALIZABLE
, silnik bazy danych przechowuje blokady wierszy i stron do końca transakcji, nawet w przypadku włączenia zoptymalizowanego blokowania, zarówno dla czytelników, jak i piszących, co powoduje zwiększone blokowanie i użycie pamięci na blokady.
Unikaj wskazówek dotyczących blokady
Podczas gdy wskazówki dotyczące tabel i zapytań, takie jak UPDLOCK
, READCOMMITTEDLOCK
, XLOCK
, HOLDLOCK
itp., są respektowane po włączeniu zoptymalizowanego blokowania, zmniejszają one korzyści płynące ze zoptymalizowanego blokowania. Wskazówki dotyczące blokady wymuszają na aparacie bazy danych tworzenie blokad wierszy lub stron i ich utrzymanie do końca transakcji, aby respektować intencje tych wskazówek. Niektóre aplikacje mają logikę, w której są potrzebne wskazówki dotyczące blokady, na przykład podczas odczytywania wiersza za pomocą wskazówki UPDLOCK
, a następnie aktualizowania go później. Zalecamy używanie wskazówek dotyczących blokady tylko w razie potrzeby.
W przypadku zoptymalizowanego blokowania nie ma żadnych ograniczeń dotyczących istniejących zapytań i nie trzeba ponownie pisać zapytań. Zapytania, które nie korzystają ze wskazówek, korzystają najwięcej z zoptymalizowanego blokowania.
Wskazówka tabeli dla jednej tabeli w zapytaniu nie wyłącza zoptymalizowanego blokowania dla innych tabel w tym samym zapytaniu. Ponadto zoptymalizowane blokowanie wpływa tylko na zachowanie blokady tabel aktualizowanych przez instrukcję DML, taką jak INSERT
, UPDATE
, DELETE
lub MERGE
. Na przykład:
CREATE TABLE t5
(
a int NOT NULL,
b int NOT NULL
);
CREATE TABLE t6
(
a int NOT NULL,
b int NOT NULL
);
GO
INSERT INTO t5 VALUES (1,10),(2,20),(3,30);
INSERT INTO t6 VALUES (1,10),(2,20),(3,30);
GO
UPDATE t5 SET t5.b = t6.b
FROM t5
INNER JOIN t6 WITH (UPDLOCK)
ON t5.a = t6.a;
W poprzednim przykładzie zapytania tylko tabela t6
jest objęta wskazówką blokującą, podczas gdy t5
nadal może korzystać z zoptymalizowanego blokowania.
UPDATE t5
SET t5.b = t6.b
FROM t5 WITH (REPEATABLEREAD)
INNER JOIN t6
ON t5.a = t6.a;
W poprzednim przykładzie zapytania tylko tabela t5
używa poziomu izolacji REPEATABLE READ
i utrzymuje blokady do końca transakcji. Inne aktualizacje t5
nadal mogą korzystać z zoptymalizowanego blokowania. To samo dotyczy wskazówki HOLDLOCK
.
Często zadawane pytania
Czy zoptymalizowane blokowanie jest domyślnie włączone zarówno w nowych, jak i istniejących bazach danych?
W usłudze Azure SQL Database tak.
Jak mogę wykryć, czy zoptymalizowane blokowanie jest włączone?
Zobacz Czy włączono zoptymalizowane blokowanie?.
Co się stanie, gdy przyspieszone odzyskiwanie bazy danych (ADR) nie jest włączone w mojej bazie danych?
Jeśli ADR jest wyłączone, zoptymalizowane blokowanie również jest automatycznie wyłączone.
Co zrobić, jeśli chcę wymusić blokowanie zapytań pomimo zoptymalizowanego blokowania?
W przypadku klientów korzystających z RCSI, aby wymusić blokowanie między dwoma zapytaniami po włączeniu zoptymalizowanego blokowania, użyj wskazówki READCOMMITTEDLOCK
.
Czy zoptymalizowane blokowanie jest używane w replikach wtórnych tylko do odczytu?
Nie, ponieważ instrukcje DML nie mogą działać na replikach tylko do odczytu, a odpowiednie blokady na poziomie wierszy i stron nie są zakładane.
Czy zoptymalizowane blokowanie jest używane podczas modyfikowania danych w bazie danych tempdb i w tabelach tymczasowych?
Nie w tej chwili.