08/11/2010 18:29:35

1.データベースの準備

a. SqlSyncScopeProvisioning の構成設定は、既にオブジェクトに追加されているテーブルにのみ適用される

Microsoft.Synchronization.Data.SqlServer.SqlSyncScopeProvisioning クラスには、SetCreateTableDefault または SetUseBulkProceduresDefault など、スコープが同期される方法を制御する構成オプションを設定するためのメソッドがいくつか含まれます。これらの設定が参照している構成オプションは、スコープに含まれる各テーブルで作成され、設定は、構成オプションが指定されたときに SqlSyncScopeProvisioning.Tables コレクションに含まれるテーブルにのみ有効となります。たとえば、次のコード例では、SqlSyncScopeProvisioning オブジェクトおよび 2 つの DbSyncTableDescription オブジェクトを作成します。最初のテーブル myTable1 はスコープに追加され、SetUseBulkProceduresDefault(false) が呼び出されます。このメソッドは、myTable1 についてのみ、一括プロシージャ構成オプションを false に設定します。これは、メソッドが、呼び出された時点でスコープに含まれるテーブルのみを構成するためです。そのため、myTable2 がスコープに追加されると、一括プロシージャを使用するように構成されます。それが既定の構成であるためです。スコープを準備するために Apply が呼び出されると、一括プロシージャは myTable1 に対して作成されず、myTable2 に対して作成されます。

 
// Create scope and tables.
DbSyncScopeDescription myScope = new DbSyncScopeDescription("myScope");
SqlSyncScopeProvisioning prov = new SqlSyncScopeProvisioning(conn, myScope);
DbSyncTableDescription myTable1 =
SqlSyncDescriptionBuilder.GetDescriptionForTable("myTable1", conn);
DbSyncTableDescription myTable2 =
SqlSyncDescriptionBuilder.GetDescriptionForTable("myTable2", conn);

// Add myTable1 to the scope. Bulk procedures are currently turned on
// for myTable1 because that is the default setting.
myScope.Tables.Add(myTable1);

// This method turns off the use of bulk procedures for myTable1,
// because it is the only table in the scope. myTable2 is not affected.
prov.SetUseBulkProceduresDefault(false);

// Add myTable2 to the scope. Bulk procedures are currently turned on
// for myTable2 because that is the default setting.
myScope.Tables.Add(myTable2);

// myTable1 is provisioned with no bulk procedures.
// myTable2 is provisioned with bulk procedures.
prov.Apply();

この状況を回避するためには、次の例のように、構成オプションを設定するメソッドを呼び出す前に、すべてのテーブルをスコープに追加します。

 
// Create scope and tables.
DbSyncScopeDescription myScope = new DbSyncScopeDescription("myScope");
SqlSyncScopeProvisioning prov = new SqlSyncScopeProvisioning(conn, myScope);
DbSyncTableDescription myTable1 =
SqlSyncDescriptionBuilder.GetDescriptionForTable("myTable1", conn);
DbSyncTableDescription myTable2 =
SqlSyncDescriptionBuilder.GetDescriptionForTable("myTable2", conn);

// Add myTable1 and myTable2 to the scope.
myScope.Tables.Add(myTable1);
myScope.Tables.Add(myTable2);

// Turn off the use of bulk procedures for all tables in the scope.
prov.SetUseBulkProceduresDefault(false);

// myTable1 and myTable2 are both provisioned with no bulk procedures.
prov.Apply();

準備の詳細については、ドキュメントの「方法: 同期スコープとテンプレートの準備と準備解除を行う (SQL Server)」を参照してください。

b. スコープ準備中の同時アクションでサポートされているシナリオ

一部のシナリオでは、準備されているプロセスにある他のアクションをデータベース上で同時に実行することがサポートされています。それ以外の状況では、エラーまたは予期しない結果が生じる場合があります。次の一覧に、サポートされるシナリオと、回避すべき状況を示します。

  • 2 つ以上のスコープを同じテンプレートから作成する場合、同じデータベースに同時に準備できます。

  • 異なるテンプレートから、またはテンプレートに基づかずに 2 つ以上のスコープを作成すると、同じデータベースに同時に準備したときに予期しない結果 (データベース内のデッドロックなど) が生じる場合があります。

  • 現在準備中のスコープを SQL Server または SQL Azure データベースに同期しようとすると、Microsoft.Synchronization.Data.DbProvisioningException がスローされます。

c. データベースが準備されていない場合に Microsoft.Synchronization.Data.DbNotProvisionedException がスローされる

d. 準備に失敗し、ロールバックできない場合に Microsoft.Synchronization.Data.DbPartiallyProvisionedException がスローされる

Microsoft.Synchronization.Data.DbPartiallyProvisionedException は、SQL Azure データベースの準備中に特定のエラーが発生した場合にスローされます。この例外は、準備トランザクションがロールバックできなかったことを示し、データベースは一貫性がない状態になります。この問題を解決するには、この例外をキャッチし、準備されたスコープまたはテンプレートを Microsoft.Synchronization.Data.SqlServer.SqlSyncScopeDeprovisioning クラスを使って準備解除する必要があります。スコープまたはテンプレートが準備解除された後、準備を再試行することができます。この例外は、SQL Azure データベースの準備中にスローされた他の例外をラップします。元の例外にはこのエラーの詳細が含まれており、DbPartiallyProvisionedException.InnerException プロパティにあります。

製品ドキュメントで、Microsoft.Synchronization.Data.DbPartiallyProvisionedExceptionMicrosoft.Synchronization.Data.SqlServer.SqlSyncProvisioningException と誤って呼ばれていることに注意してください。

2.データベースの同期

a. バッチ処理を使用すると、同期先プロバイダーが Sync Framework 2.0 を使用するときにエラーが発生する可能性がある

次の条件がすべて満たされている場合、同期は失敗します。

  • 同期中にバッチ処理が使用されている。

  • 同期元プロバイダーが Sync Framework 2.1 を使用している。

  • 同期先プロバイダーが Sync Framework 2.0 を使用している。

  • Sync Framework 2.0 と Sync Framework 2.1 がどちらも同期先のコンピューターにインストールされている。

上記のすべての条件が満たされている場合、同期先プロバイダーがバッチ ファイルのシリアル化を解除しようとしたときに、InvalidCastException をスローします。これは、バッチ ファイルのシリアル化を解除するために使用される BinaryFormatter クラスが、バッチ ファイルを生成したアセンブリのバージョンを検出するために発生します。そのため、Sync Framework 2.1 コンポーネントによってバッチ ファイルが生成されると、BinaryFormatter が Sync Framework 2.1 アセンブリを読み込んでバッチ ファイルのシリアル化を解除します。しかし、同期先プロバイダーが Sync Framework 2.0 コンポーネントを使用しているため、シリアル化を解除されたバッチは正しいオブジェクトにキャストされず、例外が発生します。このエラーは、上記のすべての条件が当てはまる場合にのみ発生します。Sync Framework 2.0 のみが同期先コンピューターにインストールされている場合、BinaryFormatter オブジェクトが 2.0 アセンブリを読み込むため、同期は正しく機能します。同期元プロバイダーが Sync Framework 2.0 を使用し、同期先プロバイダーが Sync Framework 2.1 を使用している場合、BinaryFormatter オブジェクトによって正しいアセンブリが読み込まれるようにするコードが 2.1 プロバイダーに含まれているため、同期は正しく機能します。

アプリケーションを再コンパイルせずにこの問題を解決するには、アセンブリのリダイレクトを使用して同期先プロバイダーで正しいアセンブリを読み込みます。アセンブリのリダイレクトを使用するには、マネージ アプリケーションの実行可能ファイルと同じフォルダーにアプリケーション構成 (AppName.exe.config) ファイルを追加します。次の例では、AppName.exe.config ファイルにこのエントリを追加しています。

 
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Synchronization.Data"
publicKeyToken="89845dcd8080cc91"
culture="neutral" />
<bindingRedirect oldVersion="2.1.0.0"
newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

3.重大な変更と廃止されたメンバー

Sync Framework 2.1 では、次の点が Sync Framework 2.0 から変更されています。

  • Microsoft.Synchronization.Data.SqlServerCe 名前空間のデータベース プロバイダー クラスには、SQL Server Compact 3.5 SP2 が必要になります。インストールされている SQL Server Compact のバージョンが無効な場合、SQL Server Compact データベースに接続する Sync Framework のメソッドを実行すると例外がスローされます。以前のバージョンの Sync Framework と同期する既存のデータベースがある場合は、Sync Framework と SQL Server Compact をアップグレードし、Sync Framework のメソッドを使用してデータベースに接続すると、データベースが自動的に更新されます。詳細については、製品マニュアルの「SQL Server Compact のアップグレード」を参照してください。

  • Microsoft.Synchronization.Data.SqlServer.SqlSyncScopeProvisioning オブジェクトを使用して SQL Server データベースを準備するときにテーブルおよびプロシージャを作成するための既定のオプションが、DbSyncCreationOption.Create から DbSyncCreationOption.CreateOrUseExisting に変更されています。 作成オプションに新しい値を指定せずにデータベースの準備を行うと、データベースにまだ存在していない場合にテーブルおよびプロシージャが作成されます。

  • Microsoft.Synchronization.Data.SqlServerCe.SqlCeSyncProviderAdapterConfiguration.QuotedTrackingTableName プロパティは、Microsoft.Synchronization.Data.SqlServerCe.SqlCeSyncProviderAdapterConfiguration.TrackingTableName プロパティが同じ情報を含むように変更されたため、削除されました。

  • Itanium ベースのシステムはサポートされなくなり、このプラットフォーム用のインストール パッケージはリリースされていません。

次のメンバーは、互換性のために残されています。新しい開発では使用しないでください。Sync Framework 2.1 でも引き続き問題なく使用できますが、今後のバージョンで削除される可能性があります。

  • SqlConnection パラメーターがない Microsoft.Synchronization.Data.SqlServer.SqlSyncScopeProvisioning クラスのコンストラクター (SqlSyncScopeProvisioning() および SqlSyncScopeProvisioning.(DbSyncScopeDescription))。代わりに、SqlConnection パラメーターを指定したコンストラクター (SqlSyncScopeProvisioning(SqlConnection) など) を使用してください。また、このコンストラクターの非推奨のバージョンを使用した場合、Sync Framework がデータベースのエディションを SQL Server 2005 であると見なして、挿入、更新、および削除の一括プロシージャを使用できないようにすることに注意してください。

  • SqlConnection パラメーターやデータベース名パラメーターが指定された Microsoft.Synchronization.Data.SqlServer.SqlSyncScopeProvisioning クラスのメソッド (SqlSyncScopeProvisioning.Apply(SqlConnection)SqlSyncScopeProvisioning.ScopeExists(SqlConnection)、および SqlSyncScopeProvisioning.Script(String))。代わりに、SqlSyncScopeProvisioning コンストラクターで接続を設定し、接続パラメーターが指定されていないメソッド (SqlSyncScopeProvisioning.Apply()SqlSyncScopeProvisioning.ScopeExists(String)、および SqlSyncScopeProvisioning.Script()) を使用してください。

  • SqlCeConnection パラメーターがない Microsoft.Synchronization.Data.SqlServerCe.SqlCeSyncScopeProvisioning クラスのコンストラクター (SqlCeSyncScopeProvisioning() および SqlCeSyncScopeProvisioning(DbSyncScopeDescription))。代わりに、SqlCeConnection パラメーターを指定したコンストラクター (SqlCeSyncScopeProvisioning(SqlCeConnection) など) を使用してください。

  • SqlCeConnection パラメーターが指定された Microsoft.Synchronization.Data.SqlServerCe.SqlCeSyncScopeProvisioning クラスのメソッド (SqlCeSyncScopeProvisioning.Apply(SqlCeConnection) および SqlCeSyncScopeProvisioning.ScopeExists(String, SqlCeConnection))。代わりに、SqlCeSyncScopeProvisioning コンストラクターで接続を設定し、接続パラメーターが指定されていないメソッド (SqlCeSyncScopeProvisioning.Apply()、および SqlCeSyncScopeProvisioning.ScopeExists(String)) を使用してください。