Проблема блокировки и разблокировки таблицы SQL-сервера - PullRequest
4 голосов
/ 26 августа 2011

У меня очень интересная проблема.

У меня есть таблица, где у меня есть данные, например: DVDSerialNumbers (идентификатор, дата создания, серийный номер, идентификатор категории)

Мое приложение генерирует серийные номера для DVD, и у меня есть такая команда SQL (выданная моим приложением):

ExecuteQuery("select top {0} SerialNumber from DVDSerialNumbers where CategoryID = {1};" & 
"delete from DVDSerialNumbers where ID in (select top{0} ID from DVDSerialNumber where " & 
 "CategoryID = {1});", n, CategoryID)

ExecuteQuery возвращает результат моего запроса select, но команда delete тоже выполняется.

Обычно я получаю не более n серийных номеров с указанным CategoryID и удаляю их строки.

Однако здесь у меня проблема с параллелизмом. Если приведенный выше код выполняется дважды в одно и то же время, возможно, результаты будут одинаковыми, однако идея состоит в том, чтобы получить заданный SerialNumber из таблицы только один раз.

Как я могу заставить экземпляр B ждать, пока экземпляр A завершит выполнение этой команды? Должен ли я заблокировать стол? Или я должен заблокировать несколько строк? Или есть лучшее решение?

Заранее спасибо за помощь.

1 Ответ

3 голосов
/ 26 августа 2011

Вам нужны подсказки READPAST, UPDLOCK, ROWLOCK. Подробнее см. Состояние гонки очереди процессов SQL Server

Тогда вам понадобится транзакция для SELECT / DELETE. Вместо этого вы можете сделать это одним оператором с помощью OUTPUT предложения

ExecuteQuery("delete top ({0})
                  DVDSerialNumbers WITH (READPAST, UPDLOCK, ROWLOCK)
              OUTPUT DELETED.SerialNumber
              where CategoryID = {1}" & 
                , n, CategoryID)
...