sql >> Databáze >  >> RDS >> Sqlserver

Zmatek ohledně UPDLOCK, HOLDLOCK

Proč by UPDLOCK blokoval výběry? Matice kompatibility zámku jasně ukazuje N pro spor S/U a U/S, jako v No Conflict .

Pokud jde o nápovědu HOLDLOCK, dokumentace uvádí:

HOLDLOCK:Je ekvivalentní SERIALIZABLE. Další informace naleznete v části SERIALIZABLE dále v tomto tématu.

...

SERIALIZABLE:... Kontrola se provádí se stejnou sémantikou jako transakce běžící na úrovni izolace SERIALIZABLE...

a téma Úroveň izolace transakcí vysvětluje, co znamená SERIALIZAČNÍ:

Žádné jiné transakce nemohou upravovat data, která byla aktuální transakcí přečtena, dokud se aktuální transakce nedokončí.

Jiné transakce nemohou vkládat nové řádky s hodnotami klíčů, které by spadaly do rozsahu klíčů čtených libovolnými příkazy v aktuální transakci, dokud se aktuální transakce nedokončí.

Proto je chování, které vidíte, dokonale vysvětleno v dokumentaci k produktu:

  • UPDLOCK neblokuje souběžné SELECT ani INSERT, ale blokuje UPDATE nebo DELETE řádků vybraných T1
  • HOLDLOCK znamená SERALIZABLE, a proto umožňuje SELECTS, ale blokuje UPDATE a DELETE řádků vybraných T1, také jako jakýkoli INSERT v rozsahu vybraném T1 (což je celá tabulka, tedy libovolná vložit).
  • (UPDLOCK, HOLDLOCK):váš experiment neukazuje, co by blokovalo kromě výše uvedeného případu, konkrétně další transakci s UPDLOCK v T2 :
    SELECT * FROM dbo.Test WITH (UPDLOCK) WHERE ...
  • TABLOCKX není třeba vysvětlovat

Skutečnou otázkou je, čeho se snažíte dosáhnout ? Pohrávání si s náznaky zámků bez absolutního 110% pochopení sémantiky zamykání si koleduje o potíže...

Po úpravě OP:

Chtěl bych vybrat řádky z tabulky a zabránit změnám dat v této tabulce, když ji zpracovávám.

Měli byste použít jednu z vyšších úrovní izolace transakcí. REPEATABLE READ zabrání změně čtených dat. SERIALIZABLE zabrání úpravě dat, která čtete a vkládání nových údajů. Použití úrovní izolace transakcí je správný přístup, na rozdíl od použití tipů pro dotazy. Kendra Little má pěkný plakát vysvětlující úrovně izolace.



  1. Řešení pro podporu kurzoru není implementovaná funkce pro chybu SQL Server Parallel DataWarehousing TDS

  2. Úplné šifrování MariaDB v klidu a během přepravy pro maximální ochranu dat – část první

  3. Vypočítat další primární klíč – konkrétního formátu

  4. Funkce JSON_OBJECT() v Oracle