SQL Server并发事务问题

时间:2011-12-14 09:04:06

标签: sql-server sql-server-2008 transactions

我有一种方法,它使用以下查询启动事务:

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

执行第一个插入命令后,我想更新上一​​个命令中插入item_no的{​​{1}}表中的所有items

order_item

我担心如果其他事务在现有事务运行时启动,他们可能会选择应该标记为“已使用”的套件编号,因为可能会为要标记为“已使用”的项目提交第一个事务

如果有人能就此问题提出一些建议,我们将不胜感激。

谢谢!

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

假设您使用的是支持OUTPUT clause(2005或更高版本)的SQL Server版本,我将撤消操作:

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)既选择项目又将其标记为原子不可用。

答案 2 :(得分:0)

如果我理解你的问题,你有一个项目清单,你有一个订购项目表。

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