Как в SQL Server можно заблокировать одну строку способом, аналогичным Oracle «SELECT FOR UPDATE WAIT»?

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

В версии Oracle я использую "SELECT FOR UPDATE WAIT" для блокировки определенных строк, которые мне нужны. Я использую его в ситуациях, когда обновление основано на результате SELECT и другие сеансы абсолютно не могут модифицировать его одновременно, поэтому они должны вручную сначала заблокируйте его. Система сильно подвержена сеансам, пытающимся одновременно получить доступ к одним и тем же данным.

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

BEGIN TRANSACTION;
SELECT ITEM_ID FROM TABLE_ITEM WHERE ITEM_PRIORITY > 10 AND ITEM_CATEGORY = 'CT1'
    ITEM_STATUS = 'available' AND ROWNUM = 1 FOR UPDATE WAIT 5;
UPDATE [locked item_id] SET ITEM_STATUS = 'unavailable';
COMMIT TRANSACTION;

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

Итак, наконец, вопрос: как добиться таких же результатов в SQL Server? Я искал подсказки блокировки, которые, по идее, должны работать. Однако единственными блокировками, которые предотвращают другие блокировки, являются «UPDLOCK» и «XLOCK», которые работают только на уровне таблицы.
Те подсказки блокировки, которые действительно работают на уровне строки, являются общими блокировками, которые также не удовлетворяют мои потребности (оба пользователя могут одновременно блокировать одну и ту же строку, оба помечают ее как недоступную и выполняют избыточные операции над соответствующим элементом).

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

22
задан Paradoxyde 29 February 2012 в 15:51
поделиться