簡體   English   中英

如何在SQL Server中正確管理集合

[英]How to properly manage collections in SQL Server

假定房屋有住戶,並且任何房屋的兩個住戶都不能具有相同的高度。

  1. 選擇一個隨機的房子
  2. 獲取房子的當前居住者名單
  3. 通過檢查列表來確定要保留,替換,驅逐或添加的項目
  4. 確保新列表不包含任何身高相同的乘客。
  5. 用新列表替換現有列表; 根據需要刪除,插入或更新。

聽起來很簡單,但是當您有50個線程同時嘗試執行此操作時,它將變得很復雜。 我在選擇(第2步)上使用了UPDLOCK,ROWLOCK來阻止對我可能要更新的任何乘員的可能更新。 但是,當沒有當前乘員並添加了新乘員時,我偶爾會失敗。 失敗始終是唯一的約束沖突。 這永遠都不會發生(請參閱步驟4),但確實會發生。

正在使用ReadCommitted隔離級別在TransactionScope中執行步驟2-5。

某個地方是否有最佳實踐模型來定義應如何處理這種情況?

看一下SQL Server中的事務隔離級別 聽起來您的問題很可能是幻像讀取(即有人正在將數據插入到您已經選擇的范圍中)。

在這種情況下,如果具有高級別的並發性,我絕對建議您在隔離級別設置為Serializable的單個事務中運行所有關聯的查詢(即SELECT,然后進行適當的INSERT / UPDATE / DELETE) 。 這樣,SQL Server將確保事務彼此完全隔離地進行。

但是,鑒於這種情況的最佳並發度,這種情況下的最佳解決方案可能是在代碼中實現某種鎖定/同步,而不是僅僅依靠SQL Server來完成。 (盡管如此,我仍然建議使用可序列化隔離級別。)

例如,使用某種鎖管理器,它以這樣一種方式為每個乘員和房屋生成一個鎖對象,即始終為同一乘員(或房屋)獲得相同的對象,並使每個線程都使用該對象輸入關鍵部分(或類似C#的Monitor.Enter )的方法-請注意避免死鎖。 這樣,您可以確保在任何給定時間只有一個線程正在檢查任何特定的房屋或任何特定的占用者,但仍允許其他線程運行。

我已經意識到這不是與SQL或TransactionScope相關的問題。 我正在協調數據項的集合,並且在發生這種情況時必須對訪問該集合進行信號處理。 就我而言,我只需要在執行對帳的代碼周圍添加一個lock(List){。 }

繼續進行類比,如果您要調和人員列表,則鎖定門以防止人員在進出時進出可能是一個好主意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM