Понимание поведения блокировки в SQL Server - PullRequest
5 голосов

Я попытался воспроизвести ситуацию вопроса [1].

На таблицу, взятую и заполненную данными из "Изоляции (системы баз данных)" вики [2],
в SQL Server 2008 R2 SSMS я выполнил:

1) первая в первой вкладке (окне) SSMS

-- transaction isolation level in first window does not influence results (?)
-- initially I thought that second transaction in 2) runs at the level set in first window

begin transaction 
INSERT INTO users VALUES ( 3, 'Bob', 27 )
waitfor delay '00:00:22'
rollback

2) сразу после, во втором окне

-- this is what I commented/uncommented

-- set transaction isolation level SERIALIZABLE
-- set transaction isolation level READ REPEATABLE
-- set transaction isolation level READ COMMITTED
-- set transaction isolation level READ UNCOMMITTED

SELECT * FROM users --WITH(NOLOCK)

Обновление:
Извините, результаты были исправлены.

Мои результаты, в зависимости от уровня изоляции, установленного в 2), возвращаются SELECT:

  • немедленно (чтение незафиксированной вставленной строки)

    • для всех случаев SELECT с NOLOCK
    • для READ UNCOMMITTED (ВЫБРАТЬ с или без NOLOCK)
  • ожидает завершения транзакции 1) ( ТОЛЬКО ЕСЛИ ВЫБРАТЬ без NOLOCK) и

    • в READ COMMITTED и выше (REPEATABLE READ, SERIALIZABLE) уровень изоляции транзакции

Эти результаты противоречат ситуации, описанной в вопросе (и объясненной в ответах?) [1]
(например, что SELECT с NOCHECK ожидает завершения 1)) и т. д.

Как объяснить мои результаты и [1]?


Update2:
Этот вопрос действительно подвопрос моих вопросов [3] (или результат того, что они не получили ответа).

Цитируется:
[1]
Объяснить поведение блокировки в SQL Server
Объяснить поведение блокировки в SQL Server
[2]
"Изоляция (системы баз данных)"
Плз добавить трейлинг) к ссылке. Я не могу сохранить это здесь в ссылке! http://en.wikipedia.org/wiki/Isolation_(database_systems)
[3]
Является ли NOLOCK значением по умолчанию для операторов SELECT в SQL Server 2005?
Является ли NOLOCK значением по умолчанию для операторов SELECT в SQL Server 2005?

Ответы [ 2 ]

2 голосов
/ 08 октября 2010

Существует полезная MSDN , в которой она рассказывает о подсказках по блокировке в SQL 2008. Может быть, в вашем примере это случай, когда SQL Server 2008 не поддерживает блокировки таблиц?

(В следующем фрагменте ссылки, приведенной ниже, говорится о блокировках, которые потенциально могут быть введены SQL Server 2008)

Как показано в следующем примере, если для уровня изоляции транзакции установлено значение SERIALIZABLE, а подсказка блокировки на уровне таблицы NOLOCK используется с оператором SELECT, блокировки диапазона ключей, обычно используемые для поддержки сериализуемых транзакций , не являются приняты .

CopyUSE AdventureWorks2008R2;
GO
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
GO
BEGIN TRANSACTION;
GO
SELECT Title
    FROM HumanResources.Employee WITH (NOLOCK);
GO

-- Get information about the locks held by 
-- the transaction.
SELECT  
        resource_type, 
        resource_subtype, 
        request_mode
    FROM sys.dm_tran_locks
    WHERE request_session_id = @@spid;

-- End the transaction.
ROLLBACK;
GO

Единственная принятая блокировка, которая ссылается на HumanResources.Employee, - это стабильность схемы (Sch-S), блокировка . В этом случае сериализуемость больше не гарантируется .

В SQL Server 2008 параметр LOCK_ESCALATION в LTER TABLE может отменить блокировку таблиц и включить блокировки HoBT для секционированных таблиц. Эта опция не является подсказкой блокировки, но может использоваться для уменьшения эскалации блокировки. Для получения дополнительной информации см. ALTER TABLE (Transact-SQL) .

1 голос
/ 08 октября 2010

Подсказка во втором запросе переопределяет уровень изоляции транзакции.
SELECT ... WITH (NOLOCK) в основном идентичен SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SELECT ....

При любом другом уровне изоляции блокировки учитываются, поэтому вторая транзакция ожидает дозамки открываются первым.

...