Запутался в 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 ответа:
почему блок 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, когда хотите, чтобы другие сеансы не изменяли какие-либо данные, на которые вы смотрите. Это ограничивает их возможность вставлять, обновлять или удалять заблокированные строки. Это позволяет снова запустить запрос и увидеть те же результаты.