Голяма разлика, TABLOCK
ще се опита да вземе "споделени" ключалки и TABLOCKX
изключителни брави.
Ако сте в транзакция и вземете ексклузивно заключване на маса, напр.:
SELECT 1 FROM TABLE WITH (TABLOCKX)
Никакви други процеси няма да могат да грабнатики ключалки на масата, което означава всички заявки, които се опитват да разговарят с таблицата, ще бъдат блокирани, докато транзакцията не бъде завършена.
TABLOCK
грабва само споделено заключване, споделените заключвания се освобождават след изпълнение на оператор, ако изолацията на транзакцията ви е READ COMMITTED
(по подразбиране). Ако вашето ниво на изолация е по-високо, например:SERIALIZABLE
, споделените заключвания се задържат до края на транзакцията.
Споделените ключалки са, хммм, споделени. Това означава, че и двете транзакции могат да четат данни от таблицата по едно и също време, ако и двете имат заключване S или IS на таблицата (чрез TABLOCK
). Въпреки това, ако transaction A
държи споделено заключване на маса, transaction B
няма да може да вземе изключителна ключалка, докато не бъдат освободени всички споделени ключалки. Прочетете кои ключалки с кои са съвместими в msdn.
И двата съвета карат db да заобиколи вземането на по-детайлни заключвания (като заключвания на ниво ред или страница). По принцип по-детайлните ключалки ви позволяват по-добро едновременност. Така например, една транзакция може да актуализира ред 100 във вашата таблица и друг ред 1000, в същото време от две транзакции (това става трудно със заключване на страници, но нека го пропуснем).
По принцип гранулираните заключвания са това, което искате, но понякога може да искате да намалите едновременността на db, за да увеличите производителността на конкретна операция и да елиминирате вероятността от блокиране.
По принцип не бихте използвали TABLOCK
или TABLOCKX
освен ако не ви е абсолютно необходим за някакъв край.