2017-06-09 77 views
1

我有一個問題 我的用戶。用戶在數據庫中有列 - 票。 - 票是內部貨幣。 現在當用戶點擊網站購買 - 我去webapi ===> BL(類庫)保護 - 的WebAPI

我從DB的用戶 - 檢查他是否有票,如果是的話 - 我做我的邏輯(我去到DAL - 並把這個計數器放下)。

問題是 - 如果我在網站上點擊按鈕購買 - 如此之快 - 我可以買兩次。

用戶有1票

他想買的東西 - 價格1票

用戶點擊快捷按鈕2次買入

1請求 去的WebAPI ==>去BL ==> B1中從DAL用戶需要從數據庫,並檢查他是否有票---是他已經===>做邏輯和p UT售票櫃檯爲0

2請求 進入的WebAPI ==>去BL ==> B1中採取從DAL用戶從數據庫,並檢查他是否有票---是他已經這裏的問題 ===>做的邏輯,把售票櫃檯爲0

,所以我不知道如何從這個錯誤保護....或者是如何更好地重新作出數據庫結構呢?

+0

你是直接使用ado.net還是使用實體框架(或其他)來實現ORM?我問的原因是Sql Server可以選擇使用版本控制行,EF可以利用這一點爲您提供併發檢查。如果您使用ado.net,您仍然可以利用,但必須手動實施。 – Igor

+0

使用EF 6.0的Im – Alex

+0

如果您無法處理多個按鈕事件,則可以在第一次單擊後禁用該按鈕。 –

回答

0

創建一個臨時變量,以存放在其正處理的購買狀態。 這個變量可以包含一些用戶ID。

類似:

 ' At the click... 

     If UserBuyingNow is nothing 
     UserIsBuying = User_ID 
     ... 
     (proceed to your logic) 
     ... 
     (at the end, clear the status variable) 
     UserIsBuying = null 
     else 
     (user is already buying) 
     exit 
     End If 

您也可以使用StoredProcedure的設置臨時場TRUE,同時買入和工作在SQL,在過程結束時,調用另一個StoredProcedure的清除該字段。

無論如何,邏輯是與上述相同,但在數據庫級。

3

你需要改變這樣的方式的幾個併發更新只有一個會成功的更新邏輯。

例如,如果你的數據庫表有TicketIdTicketCount領域,你看,你有n門票剩餘,你想減單的數量,而不是做這個

UPDATE Ticket 
SET [email protected] 
WHERE [email protected] 

請執行以下操作:

UPDATE Ticket 
SET [email protected] 
WHERE [email protected] AND [email protected] 

當您從多個線程同時運行第二個更新時,只有一個更新成功,更新單個行。所有其他線程都會看到這個請求更新零行。他們應該將其作爲失敗的指示,並將相應的狀態代碼返回給Web API的調用者。

我使用EF 6.0

然後你就可以依靠EF 6 implementation of optimistic concurrency,它會自動做了類似的事情給你。

+0

由於OP使用實體框架,值得注意的是,它支持開箱即用的開放式併發,並且(通過一些配置)可以產生這樣的更新查詢並在併發衝突(更新0行)時生成異常。 – Evk

+0

@Evk謝謝你,我沒有看到那條評論。 – dasblinkenlight