Таблица кучи ОБНОВЛЕНИЯ -> Блокировка на RID


8

Я настраиваю тестовый пример, чтобы доказать определенный тупиковый сценарий и требовать некоторого понимания того, что происходит. У меня есть таблица кучи, условно называемая HeapTable. Эта таблица обновляется 2 транзакциями одновременно.

Транзакция 1:

BEGIN TRAN

UPDATE HeapTable
SET FirstName = 'Dylan'
WHERE FirstName = 'Ovidiu';

WAITFOR DELAY '00:00:15';

UPDATE HeapTable
SET FirstName = 'Bob'
WHERE FirstName = 'Thierry';

ROLLBACK TRANSACTION

Транзакция 2:

BEGIN TRAN

UPDATE HeapTable
SET FirstName = 'Pierre'
WHERE FirstName = 'Michael';

ROLLBACK TRAN

Сначала я запускаю транзакцию 1, за которой следует транзакция 2. Как и ожидалось, транзакция 1 потребует несколько исключительных блокировок, а также некоторые намеренные эксклюзивные блокировки. Транзакция 2 придет и запросит блокировку обновления для того же RID:

spid dbid   ObjId       IndId   Type    Resource     Mode   Status
55    5     711673583   0       RID     1:24336:10   X      GRANT
57    5     711673583   0       RID     1:24336:10   U      WAIT

Я был немного удивлен, увидев, что вторая транзакция запрашивает блокировку обновления для того же RID, поскольку я думал, что это указывает на одну запись, и оба оператора обновления обрабатывают разные данные. Вместо этого я ожидал конфликта на уровне страницы.

Когда второе обновление транзакции 1 пинает в транзакции 2, будет рассматриваться как жертва тупика, что приведет к откату транзакции 2 и завершению транзакции 1.

Может кто-нибудь объяснить мне, почему вторая транзакция потребует блокировки обновления для того же RID, хотя обновляет другую запись?

Я знаю, как это исправить (например, с помощью индекса). Я не ищу исправления, я на самом деле ищу объяснение того, почему 2 Updates, обрабатывающие разные записи в куче, захотят заблокировать один и тот же RID. Я использую прочитанную преданную изоляцию. В таблице нет некластеризованных индексов.

Ответы:


18

Без включенного индекса FirstNameSQL Server должен проверять каждую строку, чтобы определить, подходит ли она для UPDATE.

UПри чтении каждой строки требуется блокировка обновления, чтобы предотвратить общий сценарий взаимоблокировки. Это может занять общую Sблокировку, но она все равно будет заблокирована исключительной Xблокировкой, удерживаемой первой транзакцией.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.