偵測及解決並行衝突
並行衝突發生於兩個不同的複寫上 (這兩個複寫之後會同步處理) 變更了相同的項目或變更單位時。Sync Framework 會提供變更套用者物件來簡化並行衝突的偵測與解決方案。
變更套用者如何偵測及解決並行衝突
當變更的目的地複寫版本未包含於來源複寫的知識中時,就會偵測到並行衝突。
Sync Framework 會提供變更套用者物件,目的地提供者可以使用此物件來偵測並行衝突。變更套用者會偵測並行衝突,其方式是針對來源提供者所傳送之變更批次內的每一個項目執行以下步驟:
判斷此項目之目的地複寫版本是否包含於來源複寫的知識中。
如果此項目之目的地複寫版本未包含於來源複寫的知識中,就表示此變更發生了衝突。
當變更套用者偵測到並行衝突之後,它會根據針對此工作階段所設定的衝突解決原則,或是應用程式針對指定之衝突所設定的衝突解決動作,解決此衝突。
使用變更套用者來偵測並行衝突
若要使用變更套用者來偵測變更,目的地提供者會先建立變更套用者物件。
Managed 程式碼:建立 NotifyingChangeApplier 物件。
Unmanaged 程式碼:將 IID_ISynchronousNotifyingChangeApplier 傳遞給 IProviderSyncServices::CreateChangeApplier 方法來建立 ISynchronousNotifyingChangeApplier 物件。
接下來,目的地提供者必須針對來源提供者所傳送之變更批次內的每一個項目提供版本資訊。執行這項作業的兩種方式如下:
目的地提供者會建立一份版本清單,這份清單對應到來源提供者所傳送的變更批次。變更套用者會使用這份清單來判斷項目的目的地版本是否包含於來源複寫的知識中。
Managed 程式碼:若要建立此清單,請建立 System.Collections.Generic.IEnumerable<Microsoft.Synchronization.ItemChange> 型別的物件。如果是來源提供者變更批次中的每個項目,請將項目加入至這個清單中,其中包含此項目之目的地複寫的版本。請將這份清單當做適當方法多載的 destinationVersions 參數傳遞給變更套用者,例如 ApplyChanges。
Unmanaged 程式碼:若要建立這份清單,請呼叫 IProviderSyncServices::CreateDestinationChangeVersionsBuilder 來建立 IDestinationChangeVersionsBuilder 物件。如果是來源提供者變更批次中的每個項目,請藉由呼叫 IDestinationChangeVersionsBuilder::AddItemMetadata 將項目加入至這個清單中,其中包含此項目之目的地複寫的版本。呼叫 IDestinationChangeVersionsBuilder::GetChangeEnumerator 來取得清單的列舉值,並將此列舉值當做 ApplyChanges 方法的 pDestinationVersions 參數傳遞給變更套用者。
另外,目的地提供者不會將目的地版本的清單傳遞給變更套用者,而是實作 TryGetDestinationVersion (適用於 Managed 程式碼) 或 ISynchronousNotifyingChangeApplierTarget::GetDestinationVersion (適用於 Unmanaged 程式碼) 方法。變更套用者會針對來源提供者之變更批次中的每個項目呼叫此方法一次。在此方法中,目的地提供者會尋找項目的目的地複寫版本,並將它傳回給變更套用者,好讓變更套用者可以判斷此變更是否為衝突。
最後,目的地提供者會呼叫變更套用者的 ApplyChanges (適用於 Managed 程式碼) 或 ISynchronousNotifyingChangeApplier::ApplyChanges (適用於 Unmanaged 程式碼) 方法。
使用變更套用者來解決並行衝突
變更套用者會幫助目的地提供者解決衝突,其方式是分派此提供者指定之變更套用者目標物件的呼叫。當指定衝突解決原則時,變更套用者會使用此原則來判斷每當發生衝突時所要採取的正確衝突解決動作。當指定了自訂衝突解決方案時,變更套用者會通知同步處理應用程式有關衝突的資訊,而且此應用程式會指定衝突解決動作。在任何一種情況下,變更套用者都會呼叫適當的變更套用者目標方法,而變更套用者目標物件會執行動作,例如將變更儲存到複寫或是記錄衝突以供日後處理。
同步處理應用程式在啟動同步處理之前,通常會指定並行衝突解決原則。
Managed 程式碼:應用程式會指定原則,其方式是將目的地提供者的 ConflictResolutionPolicy 屬性設定為所要的值。
Unmanaged 程式碼:應用程式會在 ISyncSession::Start 方法的 resolutionPolicy 參數中指定此原則。目的地提供者會將這個原則當做 IKnowledgeSyncProvider::ProcessChangeBatch 方法的 resolutionPolicy 參數來接收。
目的地提供者會將衝突解決原則傳遞給變更套用者,好讓變更套用者可以適當分派方法給變更套用者目標。變更套用者目標是由 INotifyingChangeApplierTarget 物件 (適用於 Managed 程式碼) 或 ISynchronousNotifyingChangeApplierTarget (適用於 Unmanaged 程式碼) 物件所表示。
Sync Framework 會定義下列並行衝突解決原則。
衝突解決原則 | 說明 |
---|---|
SourceWins (適用於 Managed 程式碼)、CRP_SOURCE_PROVIDER_WINS (適用於 Unmanaged 程式碼) |
來源複寫上所做的變更永遠優先。這會支援唯讀同步處理解決方案,其中的目的地複寫不受到信任。Sync Framework 會指定 SourceWins (適用於 Managed 程式碼) 或 SRA_ACCEPT_SOURCE_PROVIDER (適用於 Unmanaged 程式碼) 的衝突解決動作。 |
DestinationWins (適用於 Managed 程式碼)、CRP_DESTINATION_PROVIDER_WINS (適用於 Unmanaged 程式碼) |
目的地複寫上所做的變更永遠優先。這會支援目的地複寫不取用由遠端用戶端所做之變更的情形。Sync Framework 會指定 DestinationWins (適用於 Managed 程式碼) 或 SRA_ACCEPT_DESTINATION_PROVIDER (適用於 Unmanaged 程式碼) 的衝突解決動作。 |
ApplicationDefined (適用於 Managed 程式碼)、CRP_NONE (適用於 Unmanaged 程式碼) |
變更套用者會在發生每一次衝突時通知同步處理應用程式,其方式是使用 ItemConflicting 事件 (適用於 Managed 程式碼) 或 ISyncCallback::OnConflict 方法 (適用於 Unmanaged 程式碼)。應用程式會檢查發生衝突的項目,並藉由呼叫 SetResolutionAction (適用於 Managed 程式碼) 或是 IChangeConflict::SetResolveActionForChange 或 IChangeConflict::SetResolveActionForChangeUnit (適用於 Unmanaged 程式碼) 來指定衝突解決動作。 |
指定自訂衝突解決方案
為了針對所發生的每個並行衝突動態指定衝突解決動作,應用程式會在啟動同步處理之前執行以下動作。
Managed 程式碼
針對目的地提供者的 ItemConflicting 事件註冊事件處理常式。
將目的地提供者的 ConflictResolutionPolicy 屬性設定為 ApplicationDefined。
Unmanaged 程式碼
實作 ISyncCallback::OnConflict 方法,並藉由呼叫 ISyncSession::RegisterCallback 來註冊 ISyncCallback 物件。
針對 ISyncSession::Start 的 resolutionPolicy 參數傳遞 CRP_NONE。
在同步處理期間,變更套用者會針對它偵測到的每一個並行衝突引發 ItemConflicting 事件 (適用於 Managed 程式碼) 或 ISyncCallback::OnConflict 方法 (適用於 Unmanaged 程式碼) 一次。應用程式可以檢查發生衝突的兩個變更、對中繼資料或項目資料進行變更,並使用 SetResolutionAction 方法 (適用於 Managed 程式碼) 或是 IChangeConflict::SetResolveActionForChange 或 IChangeConflict::SetResolveActionForChangeUnit 方法 (適用於 Unmanaged 程式碼) 來設定衝突的解決動作。然後變更套用者會處理衝突,並分派變更套用者目標物件的適當呼叫。
注意
您必須針對項目中的所有衝突變更單位指定相同的衝突解決動作,否則可能會發生無法預期的結果。需要這種類型的衝突解決方法時,請指定要透過合併來解決衝突,並且在目的地提供者中處理解決方法。
Managed 程式碼所使用的並行衝突解決動作
Sync Framework 提供下列並行衝突解決動作集合,變更套用者會針對這些動作集合處理大部分的工作。
衝突解決動作 | 說明 |
---|---|
SourceWins |
來源複寫上所做的變更優先。變更套用者會將變更傳遞至 SaveItemChange 或 SaveChangeWithChangeUnits 方法,並指定 UpdateVersionAndData 的儲存動作。變更是套用到目的地複寫上,跟任何非衝突的變更完全一樣。 |
DestinationWins |
目的地複寫上所做的變更優先。變更套用者會將僅限版本變更傳遞至 SaveItemChange 或 SaveChangeWithChangeUnits 方法,並指定 UpdateVersionOnly 的儲存動作。系統只會在目的地複寫的中繼資料內更新項目的版本資訊,而不會進行任何項目資料變更。 |
將來源項目的資料合併到目的地項目中。變更套用者會將來源複寫的變更資料傳遞至 SaveItemChange 或 SaveChangeWithChangeUnits 方法,並指定 UpdateVersionAndMergeData 的儲存動作。目的地提供者會結合來源項目資料與目的地項目資料,並將結果套用至目的地複寫。 |
|
記錄衝突,而且不套用變更。變更套用者會將衝突資料傳遞至 SaveConflict 方法,將衝突儲存在衝突記錄檔中。如需記錄衝突的詳細資訊,請參閱記錄及管理衝突。 |
|
忽略衝突,而且不套用變更。變更套用者不會將衝突資料傳遞至目的地提供者。 |
|
最後一個寫入者優先 |
最新進行的變更優先。應用程式會擷取在來源複寫上進行變更的時間,以及在目的地複寫上進行變更的時間,其方式是針對這兩個變更呼叫 GetItemChangeTime 或 GetChangeUnitChangeTime。應用程式會比較這兩個時間,並指定最後一次變更所適用的衝突解決動作。例如,當目的地變更是最後一個變更時,應用程式會指定 DestinationWins 的衝突解決動作。 |
Unmanaged 程式碼所使用的並行衝突解決動作
Sync Framework 提供下列並行衝突解決動作集合,變更套用者會針對這些動作集合處理大部分的工作。
衝突解決動作 | 說明 |
---|---|
SRA_ACCEPT_SOURCE_PROVIDER |
來源複寫上所做的變更優先。變更套用者會將變更傳遞至 ISynchronousNotifyingChangeApplierTarget::SaveChange 或 ISynchronousNotifyingChangeApplierTarget::SaveChangeWithChangeUnits 方法,並指定 SSA_UPDATE_VERSION_AND_DATA 的儲存動作。變更是套用到目的地複寫上,跟任何非衝突的變更完全一樣。 |
SRA_ACCEPT_DESTINATION_PROVIDER |
目的地複寫上所做的變更優先。變更套用者會將僅限版本變更傳遞至 SaveChange 或 SaveChangeWithChangeUnits 方法,並指定 SSA_UPDATE_VERSION_ONLY 的儲存動作。系統只會在目的地複寫的中繼資料內更新項目的版本資訊,而不會進行任何項目資料變更。 |
SRA_MERGE |
將來源項目的資料合併到目的地項目中。變更套用者會將來源複寫的變更資料傳遞至 SaveChange 或 SaveChangeWithChangeUnits 方法,並指定 SSA_UPDATE_VERSION_AND_MERGE_DATA 的儲存動作。目的地提供者會結合來源項目資料與目的地項目資料,並將結果套用至目的地複寫。 |
SRA_TRANSFER_AND_DEFER |
記錄衝突,而且不套用變更。變更套用者會將衝突資料傳遞至 ISynchronousNotifyingChangeApplierTarget::SaveConflict 方法,將衝突儲存在衝突記錄檔中。如需記錄衝突的詳細資訊,請參閱記錄及管理衝突。 |
SRA_DEFER |
忽略衝突,而且不套用變更。變更套用者不會將衝突資料傳遞至目的地提供者。 |
最後一個寫入者優先 |
最新進行的變更優先。應用程式會擷取在來源複寫上進行變更的時間,以及在目的地複寫上進行變更的時間,其方式是針對這兩個變更呼叫 ISupportLastWriteTime::GetItemChangeTime 或 ISupportLastWriteTime::GetChangeUnitChangeTime。應用程式會比較這兩個時間,並指定最後一次變更所適用的衝突解決動作。例如,當目的地變更是最後一個變更時,應用程式會指定 SRA_ACCEPT_DESTINATION_PROVIDER 的衝突解決動作。 |
請參閱
參考
ISynchronousNotifyingChangeApplier 介面
ISynchronousNotifyingChangeApplierTarget 介面
CONFLICT_RESOLUTION_POLICY 列舉
SYNC_RESOLVE_ACTION 列舉
NotifyingChangeApplier
INotifyingChangeApplierTarget
ConflictResolutionAction
ConflictResolutionPolicy