Запутался в UPDLOCK, HOLDLOCK


при исследовании использования Табличные Подсказки, я наткнулся на эти два вопроса:

ответы на оба вопроса скажу, что при использовании (UPDLOCK, HOLDLOCK), другие процессы не смогут читать данные в этой таблице, но я этого не видел. Чтобы проверить, я создал таблица и запустил два окна SSMS. В первом окне я запустил транзакцию, выбранную из таблицы, используя различные табличные подсказки. Во время выполнения транзакции из второго окна я запускал различные инструкции, чтобы увидеть, какие будут заблокированы.

тест таблица:

CREATE TABLE [dbo].[Test](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Value] [nvarchar](50) NULL,
 CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

из окна SSMS 1:

BEGIN TRANSACTION

SELECT * FROM dbo.Test WITH (UPDLOCK, HOLDLOCK)
WAITFOR DELAY '00:00:10'

COMMIT TRANSACTION

из окна SSMS 2 (выполняется одно из следующих действий):

SELECT * FROM dbo.Test
INSERT dbo.Test(Value) VALUES ('bar')
UPDATE dbo.Test SET Value = 'baz' WHERE Value = 'bar'
DELETE dbo.Test WHERE Value= 'baz'

влияние различных табличных подсказок на выполнение операторов Окно 2:

           (UPDLOCK)       (HOLDLOCK)    (UPDLOCK, HOLDLOCK)    (TABLOCKX)
---------------------------------------------------------------------------
SELECT    not blocked      not blocked       not blocked         blocked
INSERT    not blocked        blocked           blocked           blocked
UPDATE      blocked          blocked           blocked           blocked
DELETE      blocked          blocked           blocked           blocked

Я неправильно понял ответы, данные в этих вопросах, или сделал ошибку в моем тестировании? Если нет, то почему бы вам использовать (UPDLOCK, HOLDLOCK) и ?


дальнейшее объяснение того, что я пытаюсь добиться:

Я хотел бы выбрать строки из таблицы и предотвратить изменение данных в этой таблице во время ее обработки. Я не изменяю эти данные, и хотел бы разрешить чтение происходить.

ответ четко сказано, что (UPDLOCK, HOLDLOCK) будет блокировать чтение (не то, что я хочу). Комментарии на ответ подразумевает, что это HOLDLOCK что мешает читает. Чтобы попытаться лучше понять эффекты подсказок таблицы и посмотреть, если UPDLOCK один будет делать то, что я хотел, я сделал выше эксперимент и получил результаты, которые противоречат этим ответам.

в настоящее время я считаю, что (HOLDLOCK) это то, что я должен использовать, но я обеспокоен тем, что Возможно, я ошибся или пропустил что-то, что вернется, чтобы укусить меня в будущем, поэтому этот вопрос.

2 65

2 ответа:

почему блок UPDLOCK выбирает? Элемент Блокировка Матрицы Совместимости явно показывает N для S/U и U / S утверждения, как в Нет Конфликта.

что касается аргумент holdlock Подсказка в документации говорится:

HOLDLOCK: эквивалентно сериализации. Дополнительные сведения см. В разделе сериализация далее в этой теме.

...

сериализуемый: ... Сканирование выполняется с тем же семантика как транзакция, выполняемая на уровне СЕРИАЛИЗУЕМОЙ изоляции...

и Уровень Изоляции Транзакции тема объясняет, что такое сериализуемые средства:

другие транзакции не могут изменять данные, которые были прочитаны текущей транзакции до тех пор, пока текущая транзакция не завершится.

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

поэтому поведение, которое вы видите, прекрасно объясняется документацией по продукту:

  • UPDLOCK не блокирует одновременный выбор или вставку, но блокирует любое обновление или удаление строк, выбранных T1
  • HOLDLOCK означает SERALIZABLE и поэтому позволяет выбирать, но блокирует обновление и удаление строк, выбранных T1,а также как любая вставка в диапазон, выбранный T1 (который является всей таблицей, поэтому любой вставить).
  • (UPDLOCK, HOLDLOCK): ваш эксперимент не показывает, что будет блокировать в дополнение к случаю выше, а именно еще одна транзакция с UPDLOCK в T2:
    SELECT * FROM dbo.Test WITH (UPDLOCK) WHERE ...
  • TABLOCKX нет необходимости в объяснениях

вопрос чего ты пытаешься добиться? Играть с подсказками замка без абсолютного полного 110% понимание семантики блокировки напрашивается на неприятности...

после OP edit:

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

вы должны использовать один из более высоких уровней изоляции транзакций. Повторяемое чтение предотвратит изменение данных, которые Вы читаете. Сериализуемый предотвратит изменение данных, которые Вы читаете и новые данные из вставки. Использование уровней изоляции транзакций является правильным подходом, в отличие от использования подсказок запроса. Кендра мало имеет хороший плакат, подчеркивающий уровни изоляции.

UPDLOCK используется, когда вы хотите заблокировать строку или строки во время инструкции select для будущей инструкции update. Будущее обновление может быть самым следующим оператором в транзакции.

другие сеансы все еще могу видеть данные. Они просто не могут получить блокировки, которые несовместимы с UPDLOCK и / или HOLDLOCK.

вы используете UPDLOCK, когда вы wan, чтобы другие сеансы не меняли заблокированные строки. Это ограничивает их способность обновлять или удалять заблокированные строки.

вы используете HOLDLOCK, когда хотите, чтобы другие сеансы не изменяли какие-либо данные, на которые вы смотрите. Это ограничивает их возможность вставлять, обновлять или удалять заблокированные строки. Это позволяет снова запустить запрос и увидеть те же результаты.