我們使用 LINQ - Entity Framework - SQL 得到以下查詢:
Context.Dossiers
.Include(x => x.Persons)
.ThenInclude(x=> x.Address)
.Include(x => x.Visits)
.Include(x => x.Questions)
.Include(x => x.Signatures)
.Include(x => x.Areas)
.Include(x => x.Zones)
.FirstOrDefaultAsync(x => x.Id == id)
之后我們更新檔案并保存更改。
在運行測驗客戶端后,該客戶端將針對同一請求并行發送 api 多次但具有不同的 id;我們注意到我們在 Persons 上陷入了僵局。
Persons 不會重復用于檔案,每個檔案都有自己獨特的一組人。所以沒有重疊的值被鎖定。
查看死鎖圖后,我們注意到“人員”上有一個頁面鎖定。
根據我的理解,頁面鎖會鎖定額外的記錄(甚至與查詢無關的記錄。)
所以這可能是導致我們陷入僵局的原因。
現在我的問題是:為什么 sql 將一個簡單的關系變成頁鎖而不是行鎖?(每個檔案的記錄永遠不會超過 10 人)。
這里最好的行動方案是什么?關閉升級并在禁用頁面鎖定的人員的外鍵上添加索引?或者我們可能做錯了什么?
提前感謝您的意見。
uj5u.com熱心網友回復:
可能有許多問題會觸發此問題。第一個明顯的方法是仔細檢查所有相關物體是否具有完整且有效的 FK 關系,并且這些 FK 在 EF 中被正確映射/解釋。如果這在 SQL Server 中運行,要考慮的另一個選項是查看啟用快照隔離,允許 SQL Server 更依賴于行版本控制而不是鎖。使用它的最大考慮是對 Temp DB 的影響,因此不一定推薦用于非常大的系統,尤其是在運行大量批量操作的情況下。
當您更新達析報告時,您是否需要每個包含的相關物體?使用 EF 時的另一個常見問題是在滿足對 DNRY(不要重復自己)的渴望與性能之間找到平衡。通常,這樣的代碼將作為 GetDossierById() 型別的方法駐留在 Repository 方法中,該方法在需要 Dossier 的任何地方和任何地方都被呼叫,并最終急切加載所有內容,因為其中一些區域(但不是全部)受益于擁有加載了額外的資訊。對于高度并發使用的系統,例如在任何給定時間可能有數百人更新資料的 Web 應用程式,最好將其設計為使更新盡可能具有原子性。而不是給用戶一個巨大的頁面來一次性更新整個檔案和與之相關的所有內容,然后呼叫“提交” 使用整個圖形,將其分解以通過單獨的操作提交更改。即 AddPerson、RemovePerson 等。 EF 或任何 ORM 需要一次加載的資料越多以執行操作,當系統負載時,由于“接觸”的行越多,遇到鎖定問題的風險就越大每次,并且操作通常需要更長的時間,而使鎖定的時間更長。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/324830.html
上一篇:嘗試檢索資料時出現invalidcastexception
下一篇:在拱上找到x和y
