Проблема параллельных транзакций SQL Server - PullRequest
0 голосов
/ 14 декабря 2011

У меня есть метод, где он запускает транзакцию со следующими запросами:

INSERT INTO order_item (item_no, order_id)
SELECT TOP " + Quantity + " item_no, @order_id 
FROM items where status = 'Unused'

после выполнения первой команды вставки я хочу обновить все item_no в таблице items, которая была вставлена ​​в order_item в предыдущей команде:

UPDATE items (select item_no from order_item where order_id = @order_id) 
SET status = 'Used'

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

Буду признателен, если кто-нибудь сможет дать совет по этому вопросу.

Спасибо!

Ответы [ 3 ]

4 голосов
/ 14 декабря 2011

Все это в одном с некоторым составным DML?

INSERT INTO order_item (item_no, order_id)
SELECT 
    X.item_no, @order_id
FROM
    (
    MERGE INTO items AS tgt
    USING
      (SELECT TOP (@whatever) item_no
       FROM items
       WHERE status = 'Unused'
      ) AS src ON tgt.item_no = src.item_no
    WHEN MATCHED
      UPDATE SET status = 'Used'
      OUTPUT $action as action, item_no -- $action needed for more complex stuff
    ) AS X
-- WHERE action = 'UPDATE' -- needed for more complex stuff
2 голосов
/ 14 декабря 2011

Если вы используете версию SQL Server, которая поддерживает предложение OUTPUT (2005 или более позднюю версию), я бы изменил операции:

DECLARE @Items table (item_no int /* Or varchar?, Whatever suits */ not null)
DECLARE @Quantity int

SET @Quantity = 5 /* or however this gets set */

UPDATE TOP (@Quantity) items SET status = 'Used'
OUTPUT inserted.item_no INTO @Items (item_no)
WHERE status = 'Unused'

INSERT INTO order_item (item_no,order_id)
SELECT item_no,@order_id from @Items

Таким образом, ваше первое утверждение (UPDATE) - это как выбор элементов, так и атомарная пометка их как недоступных.

0 голосов
/ 14 декабря 2011

Если я правильно понимаю вашу проблему, у вас есть инвентарь предметов и таблица заказанных предметов.

Если это правда, я думаю, вам следует переосмыслить этот механизм заказа. Я бы предпочел такой дизайн, как банковский счет и транзакции. Вы дебетуете со счетов и добавляете запись в таблицу транзакций в том же переводе БД. Мне не очень нравится эта «неиспользуемая» система флагов.

...