変更単位の同期

変更単位は、連絡先カードを表す項目における電話番号フィールドなど、サブ項目の変更を表します。プロバイダーは変更単位を使用することで、サブ項目の変更をより効率的に同期できます。変更単位を最大限に活かすことのできるプロバイダーとしては、個人情報管理ソフトウェア (PIM) のプロバイダーや、メタデータを含んだ画像を処理するプロバイダーなどが挙げられます。

変更単位

変更単位を使用すると、コンパクトなサブ項目の変更を表すことができ、より細かく変更を追跡できるようになります。このことは、項目に変更が加えられたときに発生する競合の数を減らすことにもつながります。

たとえば、ファイル システム上に存在する連絡先カードを表す項目があるとします。変更追跡の粒度が項目 (ファイル) レベルであった場合、そのファイルに対する変更はすべて項目変更と見なされ、連絡先に含まれるすべてのデータが転送されます。変更単位を使用することにより、プロバイダーは、姓、名、電話番号など、連絡先のプロパティ レベルで変更を検出し、データの競合を解決できます。この場合、2 つのレプリカの連絡先で、それぞれ異なるプロパティが変更された場合 (一方は電子メール アドレスが変更され、もう一方はイメージが添付されるなど)、項目レベルでは競合は検出されないので、該当する変更単位のデータを送信するだけで済みます。

変更単位のセットは、事実上、変更単位の順序を決定するスキーマを形成します。つまり、特定のスキーマを同期しているレプリカでは、そのスキーマに従って、変更単位の順序が決定されます。たとえば、レプリカでは、連絡先のプロパティの表現を次のように決めることができます。

Change Unit[0] = First Name

Change Unit[1] = Last Name

Change Unit[2] = Phone Number

変更単位の削除

変更単位の期間は、項目の期間にバインドされます。レプリカでは変更単位が項目のプロパティとして認識されているため、通常の変更項目とは異なり、変更単位を削除することはできません。

変更単位の追加

プロバイダーから自発的に変更単位を作成することは避けてください。悪影響が生じる可能性があります。

変更単位は、データの同期とは別に実行されるスキーマの更新に基づいて追加できます。この処理が正常に行われるためには、追加される変更単位に、すべてのレプリカに適用される既定値または null 値が割り当てられている必要があります。以降、追加された変更単位に変更が生じるまでは、その変更単位の更新バージョンが項目の作成バージョンになります。この方法で変更単位の追加を扱うことにより、アプリケーション コンポーネントからは変更単位が、更新前の状態とまったく変わっていないように見えます。

変更単位の変更の列挙

同期元プロバイダーが、変更単位を使用して、同期元レプリカから列挙されたサブ項目を表す場合、同期元プロバイダーから送信されるのは、項目全体ではなく、実際に変更された変更単位だけです。項目に変更単位が含まれる場合、バージョン情報は、項目ごとではなく、変更単位ごとに維持される点に注意してください。

マネージ コードを使用した変更単位の変更の列挙

同期元プロバイダーは、送信する変更単位を特定するために、同期先プロバイダーから受け取った SyncKnowledge オブジェクトの Contains メソッドまたは Contains メソッドを使用します。特定の変更単位の変更が同期先のナレッジに含まれていなかった場合、同期元プロバイダーから送信される変更バッチには、その変更が追加されている必要があります。

変更単位の変更は、変更バッチに追加される項目変更内に格納されます。変更単位の変更は、ItemChange コンストラクターを使用することにより、ItemChange オブジェクトの作成時に追加できるほか、AddChangeUnitChange を使って追加することもできます。

アンマネージ コードを使用した変更単位の変更の列挙

同期元プロバイダーは、送信する変更単位を特定するために、同期先プロバイダーから受け取った ISyncKnowledge オブジェクトの ISyncKnowledge::ContainsChangeUnit メソッドを使用します。特定の変更単位の変更が同期先のナレッジに含まれていなかった場合、同期元プロバイダーから送信される変更バッチには、その変更が追加されている必要があります。

変更単位の変更は、変更バッチに追加される項目変更内に格納されます。変更単位の変更を追加するには、ISyncChangeBatchBase::AddItemMetadataToGroup メソッドの ppChangeBuilder パラメーターに NULL 以外の値を指定します。次に、返された ISyncChangeBuilder オブジェクトの ISyncChangeBuilder::AddChangeUnitMetadata を使用することにより、変更単位の変更を、関連する項目変更に追加できます。

変更単位の変更の処理

同期先プロバイダーは、その ProcessChangeBatch (マネージ コードの場合) メソッドまたは IKnowledgeSyncProvider::ProcessChangeBatch (アンマネージ コードの場合) メソッドで渡された変更バッチを、Change Applier を使って処理します。このとき、同期先プロバイダーは、同期元プロバイダーから受け取った各変更について、同期先のバージョン情報を列挙します。同期元の変更に変更単位の変更が含まれている場合は、変更単位のどのバージョンを同期先バージョンのバッチに含めるかを同期先プロバイダーが決定する必要があります。この決定は、同期元プロバイダーからの変更の種類と、同期先レプリカで項目に削除マークが付いているかどうかによって異なります。同期先プロバイダーが Change Applier に送信する必要のあるバージョン情報を次の表に示します。

 

同期元の変更 = 削除

同期元の変更 = 更新

同期先の項目は削除されている

同期先項目のバージョンのみ。削除は項目全体に対してのみ許可されます。したがって、削除のバージョン情報は、項目に対して追跡されます。

同期先項目のバージョンのみ。削除は項目全体に対してのみ許可されます。したがって、削除のバージョン情報は、項目に対して追跡されます。

同期先の項目は削除されていない

すべての同期先変更単位のバージョン。

同期元から列挙された変更単位に対応する同期先変更単位のバージョンのみ。

変更単位を含んだ競合の処理

一般に、変更単位を含んだ変更に対し、アプリケーション独自の競合解決を使用する場合、その変更単位の競合に対する解決アクションを、SetResolutionAction (マネージ コードの場合) または IChangeConflict::SetResolveActionForChangeUnit (アンマネージ コードの場合) を使用して設定する必要があります。

ただし、一方のレプリカでは更新が、もう一方のレプリカでは削除が行われたことが原因で競合が発生した場合、アプリケーションは、SetResolutionAction (マネージ コードの場合) または IChangeConflict::SetResolveActionForChange (アンマネージ コードの場合) を使用して、項目の競合に対する解決アクションを指定する必要があります。

変更単位の変更の適用

通常、変更に変更単位が含まれている場合、Sync Framework は、SaveChangeWithChangeUnits (マネージ コードの場合) または ISynchronousNotifyingChangeApplierTarget::SaveChangeWithChangeUnits (アンマネージ コードの場合) を呼び出して、その変更を同期先レプリカに適用します。ただし、競合が発生し、項目を削除することによって解決されていた場合、Sync Framework は、SaveItemChange (マネージ コードの場合) または ISynchronousNotifyingChangeApplierTarget::SaveChange (アンマネージ コードの場合) を呼び出します。削除はあくまで項目全体が対象であり、個々の変更単位を削除することはできないためです。

参照

概念

標準のカスタム プロバイダーの実装