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.