Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > MS SQL Server > Как реализовать блокировку таблицы?


Автор: Povter3092 22.6.2010, 13:26
Ребята, подскажите, пожалуйста, как можно реализовать блокировку таблицы. Т.е. я хочу выполнить следующий запрос как атомарную комманду:

DECLARE @id int
SELECT TOP 1 @id = Id FROM _docIdPool
DELETE FROM _docIdPool WHERE Id = @Id
SELECT @id


Автор: tusha 22.6.2010, 13:40
Код

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

?

Добавлено через 1 минуту и 52 секунды
ну и соответственно begin/commit transaction

Добавлено через 3 минуты и 52 секунды
PS
непонятно почему ТОР 1 - для реляционных баз нету такого понятия как первая/вторая.. последняя запись в таблице. есть ключ, по нему и надо работать

Автор: Povter3092 23.6.2010, 14:53
Привет tusha. Спасибо за совет, но, к сожалению, твое решение не работает. Когда одновремено пытаются выполнить эту операцию 5 пользователей выдаётся следующая ошибка:
      Transaction (Process ID 85) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

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

Подскажите, пожалуйста, какое-нибудь решение.


Автор: kobra 24.6.2010, 11:50
Цитата(Povter3092 @  23.6.2010,  14:53 Найти цитируемый пост)
 Спасибо за совет, но, к сожалению, твое решение не работает.
как не работает? работает.
Цитата(Povter3092 @  23.6.2010,  14:53 Найти цитируемый пост)
Transaction (Process ID 85) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
проблема в том что медленно работает и таблица долго заната.
Цитата(Povter3092 @  23.6.2010,  14:53 Найти цитируемый пост)
Моя проблема заключается в следующем. У меня есть некоторая таблица с уникальными значениями. Я хочу по запросу каждому пользователю выдавать значение из этой таблицы и сразу же его удалять, чтобы никакие два пользователя не получили одинакового значения.
если генерить на хаду, будет быстрее. http://forum.sources.ru/index.php?showtopic=76795&hl=set,and,transaction,and,isolation,and,level,and,serializable&st=15

Автор: tusha 25.6.2010, 09:56
если транзакции долго ожидают снятия взаимоблокировки , то одна из них (меньшая по затратам) через некоторое время откатывается. хотя непонятно почему возникла мертвая взаимоблокировка - по идее транзакции при этом виде изоляции попросту выстраиваются в очередь. возможно это случилось когда уже какая-нибудь другая транзакция начала читать/изменять данные. попробуйте откройте 5 коннектов, в цикле на 1000 скажем итераций повторите эти действия).

Добавлено @ 09:58
http://www.rsdn.ru/article/db/deadlocks.xml

Автор: NURMS 21.7.2010, 18:17
Если для каждой транзакции использована SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, то в цикле получится deadlock, причём самый классический вариант.

А если оставить TRANSACTION ISOLATION LEVEL READ COMMITTED, то тут по идее взаимoблокировок быть не должно, зато будет чтение несуществующих данных.

Добавлено через 2 минуты и 12 секунд
А можно и сделать так:

Код


begin transaction
DECLARE @id int
SELECT TOP 1 @id = Id FROM _docIdPool with(updlock)
DELETE FROM _docIdPool WHERE Id = @Id
SELECT @id
commit transaction


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)