Пессимистическая блокировка в T-SQL
Если я ВЫБИРАЮ строку для обновления в MS SQL Server, и хочу заблокировать ее, пока я не обновлю или не отменю, какой вариант лучше: -
1) Используйте подсказку запроса, например, UPDLOCK. 2) Используйте уровень изоляции REPEATABLE READ для транзакции. 3) Любой другой вариант.
Спасибо, Чак.
3 ответа
Ни. Вы почти никогда не хотите держать транзакцию открытой, пока ваш пользователь вводит данные. Если вам нужно реализовать пессимистическую блокировку, как это, люди обычно делают это, используя свою собственную функциональность.
Подумайте о возможных последствиях того, что вы делаете. Однажды я работал над системой, в которой реализована блокировка. Вы часто сталкиваетесь с тоннами устаревших блокировок, и ваши пользователи очень быстро запутываются и злятся, когда вы навязываете им это. Решением для нас в нашем случае было полное удаление этой функциональности блокировки.
Если вы ждете другого ресурса, такого как конечный пользователь, прислушайтесь к совету Дэйва Маркла и не делайте этого.
В противном случае попробуйте следующий код T-SQL:
BEGIN TRAN
SELECT *
FROM authors AU
WITH (HOLDLOCK, ROWLOCK)
WHERE AU.au_id = '274-80-9391'
/* Do all your stuff here while the row is locked */
COMMIT TRAN
Подсказка HOLDLOCK вежливо просит SQL Server удерживать блокировку, пока вы не подтвердите транзакцию. Подсказка ROWLOCK вежливо просит SQL Server заблокировать только эту строку, а не блокировать страницу или таблицу.
Имейте в виду, что если затронуто множество строк, либо SQL Server проявит инициативу и перерастет в блокировки страниц, либо у вас будет целая армия блокировок строк, заполняющих память вашего сервера и замедляющих обработку.
Просто обратите внимание, что, несмотря на использование ROWLOCK, SQL Server может по-прежнему брать полную блокировку страницы, если сочтет это необходимым.