2011-12-14 116 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

如果我明白你的问题是正确的,你有一个物品清单,你有一个订购物品表。

如果这是真的,我认为你应该重新考虑这种排序机制。我更喜欢银行账户和交易等设计。您从账户中借记并在同一数据库转换中的交易表中添加条目。我不太喜欢这个“未使用”的标志系统。