您可以在这里采取的方法数量,但我会做类似下面的伪代码。安全的假设通常会有足够的要素来满足订单,因此围绕该假设构建交易控制并处理罕见的例外情况。
Begin transaction (Isolation = Repeatable Read)
For Each OrderDetail In Order.OrderDetailCollection
For Each OrderDetailItem In OrderDetail.OrderDetailItemCollection
Update Ingredient
Set Portions = (Portions – OrderDetailItem.Portions)
Where Ingredient.ID = OrderDetailItem.IngredientID
And (Portions – OrderDetailItems.Portions) >= 0
If RecordsAffected != 1 Then
Rollback Transaction
SufficientStock = false
Exit For
End If
Next
If(SufficientStock = false)
Exit For
End If
Next
编辑:如果你可以说服从临清一切一步之遥,另一种方法避免了往返程投资将沿着以下线的东西:在更新库存水平
Begin transaction
Insert Order (return OrderID)
Insert OrderDetails
Insert OrderDetailItems
Execute update stock stored procedure (see below)
If (Success)
Commit transaction
Else
Rollback transaction
End IF
代码程序:
CREATE PROCEDURE dbo.StockLevel_UpdateByOrderID
(
@OrderID INT
, @Success BIT
)
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL REPEATEABLE READ
BEGIN TRANSACTION
DECLARE @IngredientCount INT
-- Determine number of ingredients in whole order
SELECT
@IngredientCount = COUNT(odi.IngredientID)
FROM
dbo.OrderDetailItem odi
INNER JOIN
dbo.OrderDetail od
ON od.OrderDetailID = odi.OrderDetailID
WHERE
od.OrderID = 1
GROUP BY
odi.IngredientID
-- Update stock levels for all ingredients
UPDATE
dbo.Ingredient
SET
Portions = (i.Portions - odi.TotalPortions)
FROM
dbo.Ingredient i
INNER JOIN
(
SELECT
odi.IngredientID
, SUM(odi.Portions) AS TotalPortions
FROM
dbo.OrderDetailItem odi
INNER JOIN
dbo.OrderDetail od
ON od.OrderDetailID = odi.OrderDetailID
WHERE
od.OrderID = 1
GROUP BY
odi.IngredientID
) odi
ON odi.IngredientID = i.IngredientID
WHERE
(i.Portions - odi.TotalPortions) >= 0
-- Is number of ingredients updated correct?
IF(@@ROWCOUNT != @IngredientCount)
BEGIN
ROLLBACK TRANSACTION
SET @Success = 0
END
ELSE
BEGIN
COMMIT TRANSACTION
SET @Success = 0
END
你有一个固有的竞争条件,任何解决方案都是关于不同方法给你的可能的权衡。 – Richard 2010-05-24 11:15:19