這次目的是模擬客戶搶購商品的狀況,現在很多電商崛起,其中一個很重要的議題在於避免商品超賣,目前想到的方式由一隻Stored Procedure負責控制,當要求的商品數量大於庫存時,回傳結果但不更新商品數量代表下單失敗。所有客戶Transaction下單必須呼叫此Stored Procedure執行。
撰寫一個擁有Buy方法的Customer類別,,new出10幾個物件執行Thread,模擬消費者同時搶購的狀況。
第一次寫Stored Procedure紀錄一下ASP.NET使用Entity Framework呼叫的過程。
使用Entity Framewrok
public int Buy(int productID, int quantity)
{
int ResultQuantity = -1;
using (var db = new TestDBEntities())
{
Nullable newId = db.SP_QuantityChange_Test(productID, quantity).FirstOrDefault();
if (newId.HasValue)
{
ResultQuantity = newId.Value;
}
}
return ResultQuantity;
}
由於自己電腦的Entity Framework被我玩到環境怪怪的無法成功(同事的電腦可以成功),只好本機改使用SQL Query嘗試,順便將兩者都記錄下來。
使用SQL Query
public int Buy(int productID, int quantity)
{
int ResultQuantity = -1;
using (var db = new TestDBEntities())
{
var Params = new SqlParameter[] { new SqlParameter("@productID", productID), new SqlParameter("@quantity", quantity) };
int result = db.Database.SqlQuery(@"EXEC [dbo].[SP_QuantityChange_Test] @ID = @productID, @Quantity = @quantity", Params).FirstOrDefault();
ResultQuantity = result;
}
return ResultQuantity;
}
SQL Server預存程序內容
ALTER PROCEDURE [dbo].[SP_QuantityChange_Test] @ID INT, @Quantity INT
AS
DECLARE
@CurrentQuantity INT,
@ResultQuantity INT
BEGIN TRY
SELECT @CurrentQuantity = Product_Qty FROM C_Inventory_M WHERE Product_id = @ID
SET @ResultQuantity = @CurrentQuantity - @Quantity;
IF ( @ResultQuantity >= 0)
BEGIN
UPDATE C_Inventory_M SET Product_Qty = (@ResultQuantity) WHERE Product_id = @ID
END
SELECT CAST(@ResultQuantity as int)
END TRY
BEGIN CATCH
SELECT CAST(-1 as int)
END CATCH
另外Stored Procedure可以使用SQL DatabaseMenegement Tool逐步執行偵錯,還能使用監看式,以及可使用Try Catch,在執行失敗的時候輸出錯誤訊息存到別的Table。
參考資料:
接收預存程式回傳值:http://stackoverflow.com/questions/14735477/get-return-value-from-stored-procedure
預存程式使用TryCatch:https://technet.microsoft.com/zh-tw/library/ms179296(v=sql.105).aspx
Tags: ASP.NET
, SQL
, SQL Server
, Stored Procedure
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言