2011-12-14 113 views
0

我在這裏與下面的查詢開始事務的方法:SQL服務器併發事務問題

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

一旦第一插入命令已被執行,我想在items表更新所有item_no那插入order_item在前面的命令:

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

我很擔心,如果其他事務,而現有的運行開始時,他們可能選擇應該被標記爲「U套件編號sed',因爲第一個事務可能會被提交以將這些項目標記爲「已使用」。

如果有人能就這個問題提供一些建議,我們將不勝感激。

謝謝!

+0

您使用的是什麼版本的SQL Server? – 2011-12-14 09:11:00

回答

4

在一起使用一些可組合的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

假設你正在使用一個版本的SQL Server支持OUTPUT clause(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

即時通訊使用SQL 2008 – pothios 2011-12-14 09:16:04

+0

@ user1097386 - 那麼上述應該工作。 – 2011-12-14 09:18:24

+0

可以在沒有`@ items`表變量的情況下執行此操作,並直接將其插入輸出子句中的`order_item`。 +1 – 2011-12-14 10:05:17

0

如果我明白你的問題是正確的,你有一個物品清單,你有一個訂購物品表。

如果這是真的,我認爲你應該重新考慮這種排序機制。我更喜歡銀行賬戶和交易等設計。您從賬戶中借記並在同一數據庫轉換中的交易表中添加條目。我不太喜歡這個「未使用」的標誌系統。