您可以在這裏採取的方法數量,但我會做類似下面的僞代碼。安全的假設通常會有足夠的要素來滿足訂單,因此圍繞該假設構建交易控制並處理罕見的例外情況。
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