我有一個用 C# API .Net Core 6 實作的系統。資料庫是 SQL Server,我使用的是物體框架。我有一個單獨的庫存專案表(每個專案都有自己的記錄)。當我出售一件商品時,我通過將“已售”欄位的值從 NULL 更改為 DateTime.UtcNow 來記錄其銷售日期。當我需要出售一件商品時,我想在我的庫存表中獲得該類別的商品之一的參考,我使用 ctx.Stock.Where(t=> t.Sold == null && t.Category= =cat).First() 如果存在則回傳一個專案。然后該專案的“已售”欄位會更新。
由于系統是通過 API 訪問的,因此似乎可以同時呼叫兩次(或多次)代碼,兩次呼叫都會從 ctx.Stock.Where(t=> t.Sold == null && t.Category==cat).First() ,然后兩者都將其標記為已售出,并且當為它們兩者呼叫 SaveChanges 時,它將保存后來的“已售”值,并且只會記錄 1 個股票記錄實際上發生了 2 次銷售時已售出。
現在,如果在這種情況發生時觸發 DbUpdateConcurrencyException,則可以避免這種情況。有誰知道這是否會是這種情況?在那種情況下,我猜想可以實作一個重試回圈來嘗試使用 ctx.Stock.Where(t=> t.Sold == null && t.Category==cat).First() 獲取新的股票記錄。這會是最好的方法嗎?
否則將有一個單例服務,該服務在 ctx.Stock.Where(t=> t.Sold == null && t.Category==cat).First() 和填充的“Sold”欄位的 SaveChanges 的運行中具有鎖更好的選擇?這可以確保沒有可能的 DbUpdateConcurrencyException 因為它是連續的,但是鎖可能會成為問題。
uj5u.com熱心網友回復:
我不太喜歡信任資料庫。如果您希望能夠水平擴展您的應用程式并訪問 Redis 快取,您可以使用RedLock來防止兩個呼叫同時訪問資料庫。否則只需使用簡單的鎖。該服務不必是單例...您只需要使用靜態物件進行鎖定。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/480066.html
