開放式並行存取:總覽
LINQ to SQL 支援開放式同步存取控制。 下表描述 LINQ to SQL 文件中與開放式同步存取相關的術語:
詞彙 | 描述 |
---|---|
concurrency | 兩位以上的使用者同時嘗試更新相同資料庫資料列的情況。 |
並行衝突 | 兩位以上的使用者同時嘗試將衝突值送出給資料列的一個或多個資料行的情況。 |
並行控制 | 用來解決並行衝突的技術。 |
開放式並行存取控制項 | 此種技術會先檢查資料列中的其他異動是否已變更值,才允許送出變更。 與「封閉式並行存取控制」相反,封閉式並行存取控制會鎖定記錄以避免並行衝突。 稱為「開放式」控制的原因是,其會將某個異動干擾另一個異動的機會視為不可能。 |
衝突的解決方式 | 透過再次查詢資料庫,然後調整差異,以重新整理衝突項目的處理流程。 重新整理物件時,LINQ to SQL 變更追蹤器會保留下列資料: - 一開始取自資料庫並用於更新檢查的值。 - 來自後續查詢的新資料庫值。 LINQ to SQL 接著會判斷物件是否發生衝突 (亦即,其中一或多個成員值是否變更)。 如果物件發生衝突,則 LINQ to SQL 會接著判斷它的哪個成員發生衝突。 LINQ to SQL 發現的所有成員衝突都會新增至衝突清單中。 |
在 LINQ to SQL 物件模型中,開放式同步存取衝突會在下列兩個條件都成立時發生:
用戶端嘗試將變更送出給資料庫。
資料庫中的一個或多個更新檢查值,自用戶端最後一次讀取之後已更新過。
解決這項衝突包括探索哪些物件成員發生衝突,然後決定要採取的動作。
注意
只有對應成 Always 或 WhenChanged 的成員才會參與開放式並行存取檢查。 而不會檢查標記為 Never 的成員。 如需詳細資訊,請參閱UpdateCheck。
範例
例如,在下列案例中,User1 查詢資料庫中的資料列,開始準備更新。 User1 會接收到值為 Alfreds、Maria 和 Sales 的一個資料列。
User1 想將 Manager 資料行的值變更為 Alfred,並將 Department 資料行的值變更為 Marketing。 但是在 User1 送出那些變更之前,User2 就已經先送出變更給資料庫。 因此,現在 Assistant 資料行的值已變更為 Mary,而 Department 資料行的值已變更為 Service。
如果 User1 現在嘗試送出變更,則送出會失敗,而且會擲回 ChangeConflictException 例外狀況。 因為 Assistant 資料行和 Department 資料行的資料庫值並不是所預期的值,所以會發生這種結果。 因此表示 Assistant 和 Department 資料行的成員會產生衝突。 下表將摘要說明這種情況。
州/省 | 管理員 | 小幫手 | 部門 |
---|---|---|---|
原始狀態 | Alfreds | Maria | Sales |
User1 | Alfred | 行銷 | |
User2 | Mary | 服務 |
您可以使用不同方式來解決這類衝突。 如需詳細資訊,請參閱作法:管理變更衝突。
衝突偵測和解決檢查清單
您可以偵測和解決任何精細度等級的衝突。 其中一種極端的做法是,使用三種方式的其中一種方式來解決所有的衝突 (請參閱 RefreshMode),而不考慮其他事項。 另一種極端的做法是,指定每個衝突成員之每種衝突類型的特定動作。
指定或修訂物件模型中的 UpdateCheck 選項。
如需詳細資訊,請參閱作法:指定用於測試並行衝突的成員。
在 SubmitChanges 呼叫的 try/catch 區塊中,指定何時擲回例外狀況。
如需詳細資訊,請參閱作法:指定並行例外狀況的擲回時機。
決定想要擷取的衝突詳細資料量,並據此將程式碼併入 try/catch 區域。
如需詳細資訊,請參閱作法:擷取實體衝突資訊與作法:擷取成員衝突資訊。
在
try
/catch
程式碼中併入想要解決所發現之各種衝突的方式。如需詳細資訊,請參閱作法:透過保留資料庫值來解決衝突、作法:透過覆寫資料庫值來解決衝突,以及作法:透過與資料庫值合併來解決衝突。
支援衝突探索和解決的 LINQ to SQL 型別
LINQ to SQL 中支援解決開放式同步存取衝突的類別和功能包括: