2016-08-03 4 views
3

Я пытаюсь выполнить следующие два запроса в SQL Server Management Studio (в отдельных окнах запросов). Я запускаю их в том же порядке, что и набрал их здесь.Read Committed vs Repeatable Пример чтения

Когда уровень изоляции установлен на READ COMMITTED, они выполняются нормально, но когда он установлен в REPEATABLE READS, транзакции заблокированы.

Не могли бы вы помочь мне понять, что здесь мертво заблокировано?

Первое:

begin tran 
declare @a int, @b int 
set @a = (select col1 from Test where id = 1) 
set @b = (select col1 from Test where id = 2) 
waitfor delay '00:00:10' 
update Test set col1 = @a + @b where id = 1 
update Test set col1 = @a - @b where id = 2 
commit 

Второе:

begin tran 
update Test set col1 = -1 where id = 1 
commit 

UPD Ответ laready дал, но folowing совет я вставив тупиковый граф

enter image description here

+0

Вы пробовали создать столкнутый график в профилировщике? – SQLChao

ответ

1

В обоих случаях выбор использует общую блокировку, а обновления - исключительную блокировку.

В режиме READ COMMITTED общий замок освобождается сразу после окончания выбора.

В режиме REPEATABLE READS разделяемые блокировки для выборок сохраняются до конца транзакции, чтобы гарантировать, что никакие другие сеансы не могут изменить прочитанные данные. Новое чтение в рамках одной транзакции гарантировано для получения тех же результатов, если данные не были изменены в текущем сеансе/транзакции

Первоначально я думал, что вы выполнили «Первое» в обеих сессиях. Тогда объяснение будет тривиальным: оба сеанса приобретают и получают общую блокировку, которая затем блокирует исключительную блокировку, необходимую для обновлений.

Ситуация со вторым сеансом, выполняющим только обновление, немного сложнее. Обновление будет сначала получать блокировку обновления (UPDLOCK) для выбора строк, которые должны быть обновлены, что, вероятно, похоже на общую блокировку, но по крайней мере не блокируется общей блокировкой. Затем, когда данные фактически обновляются, он пытается преобразовать блокировку обновления в исключительную блокировку, которая не выполняется, поскольку первый сеанс все еще удерживает общую блокировку. Теперь обе сессии блокируют друг друга.