Редагувати: як зазначає @MaxVernon , наступне - це жодним чином не пропонувати NOLOCK , і я дуже добре повинен був би згадати про встановлення рівня транзакції, READ UNCOMMITEDі щоб негативна конотація стояла там, а не NOLOCKпіднімалася на першому місці. Отже, як було розміщено спочатку:
Швидкий і простий - "Так, перший запит заблокує другий запит, якщо не вказано конкретний підказку індексу ( NOLOCK , іноді називається" брудним зчитуванням ") або встановлено рівень ізоляції транзакцій другого запиту READ UNCOMMITED(який працює однаково), ні, це не є."
У відповідь на додаткову деталь, надану у питанні, що передбачає включення а WITH пункту на другий SELECT, будучи взаємовиключним або іншим чином, взаємодії між двома запитами будуть в основному однаковими.
IF NOT EXISTS ( SELECT 1
FROM sys.objects
WHERE name = 'Foo'
AND type = 'U' )
BEGIN
--DROP TABLE dbo.Foo;
CREATE TABLE dbo.Foo
(
Foo_PK BIGINT IDENTITY( 1, 1 ) NOT NULL,
PRIMARY KEY ( Foo_PK ),
Bar BIT,
x BIT,
y BIT,
z BIT
);
CREATE NONCLUSTERED INDEX IX_Foo_x
ON dbo.Foo ( x );
INSERT INTO dbo.Foo ( Bar, x, y, z )
VALUES ( 1, 1, 1, 1 ), ( 0, 0, 0, 0 );
END;
GO
BEGIN TRANSACTION;
UPDATE dbo.Foo
SET y = 0
WHERE x = 1;
-- COMMIT TRANSACTION;
В окремому сеансі виконайте наступне:
SELECT *
FROM dbo.Foo WITH ( NOLOCK );
GO
SELECT *
FROM dbo.Foo;
Ви можете перевірити блокування, які зараз утримуються, запустивши sp_lock , бажано, в інший окремий сеанс:
EXECUTE dbo.sp_lock;
Ви повинні бачити KEYблокування типу, яке тримає павук, який виконує транзакцію з вставкою в X(ексклюзивному) режимі, і не плутати його з іншими IXблоками (ексклюзивні намір). Документація щодо блокування вказує на те, що в той час, коли KEYзамок є специфічним для діапазону, він також запобігає іншим транзакціям вставляти або оновлювати порушені стовпці, змінюючи дані, що містяться в ньому, щоб він міг потрапляти в цей діапазон вихідного запиту. Оскільки замок, який утримується, є ексклюзивним, перший запит запобігає доступу до ресурсу з будь-якої іншої одночасної транзакції. Насправді всі рядки стовпця заблоковані, незалежно від того, потрапляють вони чи ні в діапазон, визначений першим запитом.
Таким чином, Sблокування, проведене на другому сеансі, триватиме WAITдо моментуX блокування не очиститься, не запобігаючи прийому іншого X(або U) блокування на цьому ресурсі від іншого одночасного шпіона до того, як другий сеанс завершить свою операцію читання, виправдовуючи існування Sблокування.
Тепер редагування для ясності: Якщо я не помиляюся з тим, що брудне прочитання - це короткий опис згаданих тут ризиків ... Edit 3 : Я щойно зрозумів, що не розглядаю ефект фонової контрольної точки, яка пише як ще не підтвердженої транзакції на диску, так що так, моє пояснення було вводити в оману.
У другому запиті перша партія може (і в цьому випадку буде) повертати незапущені дані. Друга партія, що працює на рівні ізоляції транзакцій за замовчуванням READ COMMITED, повернеться лише після того, як фіксація або відкат буде виконано в першому сеансі.
Звідси ви можете переглянути свої плани запитів та пов'язані з ними рівні блокування, але ще краще, про все про блокування на SQL Server ви можете прочитати тут .
SELECT * FROM Table1якщо це саме те, що мені потрібно?