這次目的是模擬客戶搶購商品的狀況,現在很多電商崛起,其中一個很重要的議題在於避免商品超賣,目前想到的方式由一隻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()) { NullablenewId = 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)
沒有留言:
張貼留言