10/07/2009 22:01:58
This Release Notes document describes breaking changes and known issues that you should read about before you install or troubleshoot Microsoft Sync Framework 2.0.
-
Installing Sync Framework
-
Database Providers
-
Core Components
-
Breaking Changes
-
Some Methods May Return Errors That Do Not Contain a Useful Error Message
-
Change Units Are Not Restored After a Delete-Update Conflict when Simple Providers and Change Unit Filters Are Used
-
Filtered Replicas Cannot Perform Full Enumeration for Recovery Synchronization
-
Tombstone Cleanup on Filtered Replicas Require Additional Processing
-
Custom Filters Cannot Be Used with Change Units
-
Breaking Changes
-
Documentation and Samples
1. Installing Sync Framework
a. Uninstall Sync Framework Preview Release Before Installing Final Release
Sync Framework 2.0 cannot be installed on a computer that has a Sync Framework 2.0 Community Technology Preview (CTP) release installed. This means that it is not possible to upgrade from Sync Framework 2.0 CTP1 or CTP2 to the RTM release of Sync Framework 2.0. To install Sync Framework 2.0, first uninstall any Sync Framework 2.0 CTP releases.
Sync Framework 2.0 can be installed and will operate side-by-side with Sync Framework 1.0.
2. Database Providers
a. Breaking Changes
The following changes occurred between Sync Framework 1.0 and Sync Framework 2.0.
-
The Microsoft.Synchronization.Data.RelationalSyncProvider base class was created to encapsulate the logic that is common across all of the Sync Framework database providers. Many of the members from DbSyncProvider were moved to RelationalSyncProvider, but the overall API surface did not change significantly. Microsoft.Synchronization.Data.DbSyncProvider, Microsoft.Synchronization.Data.SqlServer.SqlSyncProvider, and Microsoft.Synchronization.Data.SqlServerCe.SqlCeSyncProvider all inherit from RelationalSyncProvider.
-
The SyncConflict collection that was available from Microsoft.Synchronization.Data.DbSyncTableProgress has been removed. This was a performance optimization to reduce memory usage for synchronization sessions with a large number of conflicts. It is now recommended to interact with conflicts on an individual basis by using the ApplyChangeFailed event for each provider.
The following changes occurred between Sync Framework 2.0 CTP2 and Sync Framework 2.0 final release version.
-
Removed the Microsoft.Synchronization.Data.SqlServer.SqlSyncProviderAdapterConfiguration.PkColumnNames property. You should now use the Microsoft.Synchronization.Data.SqlServer.SqlSyncProviderAdapterConfiguration.Columns property instead.
-
The following collections were changed to enumerable collections so that they adhere to existing patterns used for popular ADO.Net types such as DataSet:
-
Microsoft.Synchronization.Data.DbSyncTableDescription, which is available through the Microsoft.Synchronization.Data.DbSyncScopeDescription.Tables property.
-
Microsoft.Synchronization.Data.SqlServer.SqlSyncTableProvisioning, which is available through the Microsoft.Synchronization.Data.SqlServer.SqlSyncScopeProvisioning.Tables property.
-
Microsoft.Synchronization.Data.SqlServerCe.SqlCeSyncTableProvisioning, which is available through the Microsoft.Synchronization.Data.SqlServerCe.SqlCeSyncScopeProvisioning.Tables property.
-
Microsoft.Synchronization.Data.DbSyncTableDescription, which is available through the Microsoft.Synchronization.Data.DbSyncScopeDescription.Tables property.
-
The Microsoft.Synchronization.Data.DbSyncColumnDescription.GetInitialParameterName method was converted to a property to conform to API design best practices. You should now use the Microsoft.Synchronization.Data.DbSyncColumnDescription.ParameterName property instead.
-
The name of the snapshot initialization method was changed to Microsoft.Synchronization.Data.SqlServerCe.SqlCeSyncStoreSnapshotInitialization.InitializeFromSnapshot.
b. Compact() Command Can Cause Non-Convergence of Data
When a database provider is used to represent a replica that stores data in a Microsoft SQL Server Compact database, and the Compact() command is used to reclaim space in the database, incorrect values can occur in the metadata that Sync Framework uses to track changes in the database. If possible, use the Shrink() command instead of the Compact() command, or apply the hotfix that addresses this issue:
c. Database Provisioning Can Result in Serialization Errors
In some cases, Sync Framework uses the XmlIgnoreAttribute
attribute when provisioning databases. In older versions of the .NET Framework, the use of XmlIgnoreAttribute
results in the following exception:
Message: Unable to generate a temporary class (result=1). error CS0200: Property or indexer 'Microsoft.Synchronization.Data.DbSyncColumnDescription.IsNullableSpecified' cannot be assigned to -- it is read only error CS0200: Property or indexer 'Microsoft.Synchronization.Data.DbSyncColumnDescription.IsPrimaryKeySpecified' cannot be assigned to -- it is read only |
To avoid this problem, ensure that you have the .NET Framework 2.0 SP1 or later installed on the computer on which the Sync Framework database provider is running.
d. Database Provisioning Fails for Windows' Least-Privilege User Account (LUA)
If the synchronization process is running under LUA, the following error is thrown when attempting to provision a database:
Message: Unable to generate a temporary class (result=1). error CS2001: Source file 'D:\WINDOWS\TEMP\ycwdmrz3.0.cs' could not be found error CS2008: No inputs specified |
This error occurs because the Xml serializer that Sync Framework uses requires read and write access to the Windows temp directory, which LUA does not allow.
e. Sample Application Throws a Deserialization Exception
When the sample application attempts to set the synchronization batch size to a non-zero value, the following exceptions are thrown:
Outer Exception: An unexpected error occurred when applying batch file. Inner Exception: Attempting to deserialize an empty stream. |
To fix the sample application, modify the GetChangeBatch()
method in RelationalProviderProxy.cs
(line106) so that the instantiation of the Filestream
object is inside the If
statement.
//ORIGINAL CODE string localFileName = Path.Combine(this.localBatchingDirectory.FullName, context.BatchFileName); FileInfo localFileInfo = new FileInfo(localFileName); //Download the file only if it doesn't exist FileStream localFileStream = new FileStream(localFileName, FileMode.Create, FileAccess.Write); if (!localFileInfo.Exists) { byte[] remoteFileContents = this.proxy.DownloadBatchFile(context.BatchFileName); using (localFileStream) { localFileStream.Write(remoteFileContents, 0, remoteFileContents.Length); } } } } //UPDATED CODE string localFileName = Path.Combine(this.localBatchingDirectory.FullName, context.BatchFileName); FileInfo localFileInfo = new FileInfo(localFileName); if (!localFileInfo.Exists) { //Download the file only if doesnt exist FileStream localFileStream = new FileStream(localFileName, FileMode.Create, FileAccess.Write); byte[] remoteFileContents = this.proxy.DownloadBatchFile(context.BatchFileName); using (localFileStream) { localFileStream.Write(remoteFileContents, 0, remoteFileContents.Length); } } |
3. Core Components
a. Breaking Changes
The following changes occurred between Sync Framework 1.0 and Sync Framework 2.0.
-
The Microsoft.Synchronization.FilterType enumeration (for managed code) and the FILTER_TYPE enumeration (for unmanaged code) are not used and have been removed. Any references to these enumerations in your code must also be removed.
The following changes occurred between Sync Framework 2.0 CTP2 and Sync Framework 2.0 RTM in the Microsoft.Synchronization.SimpleProviders namespace.
-
The following classes and methods were removed.
-
The AnchorEnumerationContext constructor.
-
The AnchorEnumerationSimpleSyncProvider.EnumerateItems method.
-
The ISimpleSyncProviderIdGenerator.GenerateNewReplicaId method.
-
The RecoverableErrorReportingContext.RecordRecoverableErrorForChangeUnit method.
-
The SimpleSyncProvider.ChangeReplicaId method.
-
The ChangeDetectionFailedException class.
-
The CustomConflictResolutionNotSupportedException class.
-
The ItemSchemaNotDefinedException class.
-
The NewItemDoesNotContainAllFieldsException class.
-
The NoCommonChangeUnitsException class.
-
The UnknownChangeUnitException class.
-
The AnchorEnumerationContext constructor.
-
The following methods were renamed or parameters were changed.
-
The AnchorEnumerationContext.AutodetectDeletes method was renamed to AnchorEnumerationContext.ReportItemsAndAutodetectDeletes and the method parameters were changed.
-
The AnchorEnumerationSimpleSyncProvider.EnumerateChanges method parameters were changed.
-
The ISimpleSyncProviderIdGenerator.GenerateNewItemId method parameters were changed.
-
The ItemFieldDictionary class no longer implements the System.Collections.ICollection interface.
-
The SimpleSyncServices constructor parameters were changed.
-
The SimpleSyncServices.CleanupTombstones method was renamed to SimpleSyncServices.CleanupDeletedItems.
-
The UnmanagedSimpleSyncProviderWrapper.UnmanagedSimpleSyncProviderWrapper constructor parameters were changed.
-
The UnmanagedSimpleSyncProviderWrapper.Initialize method parameters were changed.
-
The AnchorEnumerationContext.AutodetectDeletes method was renamed to AnchorEnumerationContext.ReportItemsAndAutodetectDeletes and the method parameters were changed.
-
The following classes were moved from the Microsoft.Synchronization.SimpleProviders namespace to the Microsoft.Synchronization namespace.
-
ChangeDeferredByProviderException
-
ChangeReplicaIdPendingException
-
DuplicateItemException
-
ItemNotFoundInMetadataStoreException
-
MetadataStoreVersion2RequiredException
-
OptimisticConcurrencyException
-
RecoverableErrorMustFailEntireItemException
-
SimpleProviderInvalidOperationException
-
SimpleProvidersException
-
ChangeDeferredByProviderException
b. Some Methods May Return Errors That Do Not Contain a Useful Error Message
Some methods may return a generic error message, such as "Exception from HRESULT: 0x80041006", instead of a description of what caused the error. The following table lists the error codes and their values. For descriptions of these error codes, see Sync Framework Error Codes in the Sync Framework Core Components reference.
Error code | Error code value |
---|---|
SYNC_E_ID_FORMAT_MISMATCH |
0x80041000 |
SYNC_E_INVALID_OPERATION |
0x80041001 |
SYNC_E_REPLICA_NOT_FOUND |
0x80041002 |
SYNC_E_CHANGE_COUNT_MISMATCH |
0x80041003 |
SYNC_E_CHANGE_UNIT_COUNT_MISMATCH |
0x80041004 |
SYNC_E_KNOWLEDGE_DECREASED |
0x80041005 |
SYNC_E_CHANGE_NOT_IN_KNOWLEDGE |
0x80041006 |
SYNC_E_ITEM_MUST_EXIST |
0x80041007 |
SYNC_E_HAS_NO_DATA |
0x80041008 |
SYNC_E_CHANGE_NEEDS_KNOWLEDGE |
0x80041009 |
SYNC_E_RANGE_OUT_OF_ORDER |
0x8004100A |
SYNC_E_NOT_EXPECTED_CHANGE |
0x8004100B |
SYNC_E_DESERIALIZATION |
0x8004100C |
SYNC_E_SINGLE_RANGE_ONLY |
0x8004100D |
SYNC_E_ITEM_HAS_CHANGE_UNITS |
0x8004100E |
SYNC_E_ITEM_HAS_NO_CHANGE_UNITS |
0x8004100F |
SYNC_E_ITEM_HAS_NO_VERSION_DATA |
0x80041010 |
SYNC_E_OBJECT_NEEDS_STATE |
0x80041011 |
SYNC_E_FEEDSYNC_INVALID_FEED |
0x80041012 |
SYNC_E_FEEDSYNC_ITEM_NOT_IN_METADATA |
0x80041013 |
SYNC_E_FEEDSYNC_CALLBACK_EXPECTED |
0x80041014 |
SYNC_E_INVALID_VERSION |
0x80041015 |
SYNC_E_DUPLICATE_ITEM |
0x80041016 |
SYNC_E_INVALID_ORDER_FOR_VECTOR_ELEMENTS |
0x80041017 |
SYNC_E_INVALID_SYNC_TIME |
0x80041018 |
SYNC_E_INCOMPLETE_REPLICA_KEY_MAP |
0x80041019 |
SYNC_E_INVALID_REPLICA_KEY |
0x8004101A |
SYNC_E_NEGATIVE_RANGE_EXCEPTION |
0x8004101B |
SYNC_E_BATCH_NEEDS_KNOWLEDGE |
0x8004101C |
SYNC_E_INTERNAL_ERROR |
0x8004101D |
SYNC_E_CHANGE_BATCH_IS_READ_ONLY |
0x8004101E |
SYNC_E_DATA_MODIFIED_CONCURRENTLY |
0x8004101F |
SYNC_E_ON_CREATE_MUST_FAIL_ENTIRE_ITEM |
0x80041020 |
SYNC_E_FILTER_NOT_SUPPORTED |
0x80041021 |
SYNC_E_LOAD_CONFLICT_DATA_FAILED |
0x80041022 |
SYNC_E_INVALID_SERIALIZATION_VERSION |
0x80041023 |
SYNC_E_MARKER_MISMATCH |
0x80041024 |
SYNC_E_FORGOTTEN_KNOWLEDGE_NOT_CONTAINED |
0x80041025 |
SYNC_E_ACTIVE_CHANGE_APPLICATION_CONTEXT |
0x80041026 |
SYNC_E_ITEM_LIST_FILTERED_FULL_ENUMERATION_NOT_SUPPORTED |
0x80041027 |
SYNC_E_FULL_ENUMERATION_MUST_BE_USED |
0x80041028 |
SYNC_E_BATCH_NEEDS_FILTER_FORGOTTEN_KNOWLEDGE |
0x80041029 |
SYNC_E_CONSTRAINT_CONFLICT_NOT_ALLOWED |
0x8004102A |
SYNC_E_SOURCE_DOES_NOT_TRACK_FILTER |
0x8004102B |
c. Change Units Are Not Restored After a Delete-Update Conflict when Simple Providers and Change Unit Filters Are Used
This situation occurs when simple providers are used and one of the replicas in the synchronization community uses a change unit filter. The steps that cause this situation are as follows:
-
Item I is deleted from unfiltered replica A, and the tombstone is then removed.
-
Item I is updated on replica B. Replica B uses a change unit filter and so does not store all change units for the item.
-
Synchronization is performed using replica B as the source replica and replica A as the destination replica.
-
A delete-update conflict is detected on item I and is resolved in favor of the update on replica B. Item I is restored on replica A, but contains data only for the change units that are stored on replica B. The version of all change units is updated to the new version.
-
Synchronization is again performed, this time using unfiltered replica C as the source replica and replica A as the destination replica.
-
The missing change units for item I are not sent from replica C, because their versions on replica A are later than their versions on replica C.
To work around this situation, update the change units for item I on replica C so that their versions are later than the versions on replica A, and then synchronize from replica C to replica A.
d. Filtered Replicas Cannot Perform Full Enumeration for Recovery Synchronization
When the destination replica is out-of-date and recovery synchronization must be performed, the source replica must be an unfiltered replica to fully recover the out-of-date replica. When the source replica is a filtered replica, the source provider must not perform a full enumeration or unexpected results may occur.
In this situation, the filtered source replica can perform a partial synchronization with the out-of-date destination replica. To do this, the application specifies FullEnumerationAction.Partial in response to the FullEnumerationNeeded event (for managed code) or SFEA_PARTIAL_SYNC in response to the ISyncCallback::OnFullEnumerationNeeded callback method (for unmanaged code). The application may also cancel synchronization by specifying FullEnumeration.Abort (for managed code) or SFEA_ABORT (for unmanaged code).
e. Tombstone Cleanup on Filtered Replicas Require Additional Processing
When a filtered replica uses the snapshot technique to clean up tombstones, additional care must be taken to ensure the knowledge of the replica always contains the forgotten knowledge of the replica. This is because situations can arise where the knowledge of a filtered replica is reduced because of an item moving in relation to the filter.
Cleaning up tombstones by using managed code
Do not use the snapshot technique when cleaning up tombstones on a filtered replica. Instead, perform the following steps to remove a tombstone:
-
Call ForgottenKnowledge.ForgetTo, passing the change version of the tombstone to be removed. If this method succeeds, perform step 2.
-
Remove the tombstone from the replica metadata.
Cleaning up tombstones by using unmanaged code
To use the snapshot technique to clean up tombstones on a filtered replica, perform the following steps:
-
Project the snapshot knowledge using the current knowledge as the template knowledge. To do this, call ISyncKnowledge2::ProjectOntoKnowledgeWithPrerequisite on the snapshot knowledge, passing the snapshot knowledge for pPrerequisiteKnowledge and the current knowledge of the replica for pTemplateKnowledge. Use the projected knowledge that is returned from this method in the next steps.
-
Remove tombstones from the replica that are contained in the projected snapshot knowledge.
-
Combine the forgotten knowledge of the replica with the projected snapshot knowledge and store the result as the new forgotten knowledge of the replica.
-
Save the current knowledge of the replica as the new snapshot knowledge.
The snapshot technique is recommended because it keeps the knowledge smaller and more efficient. However, the following steps can also be followed to remove a tombstone:
-
Call IForgottenKnowledge::ForgetToVersion, passing the change version of the tombstone to be removed. If this method succeeds, perform step 2.
-
Remove the tombstone from the replica metadata.
Custom Filters Cannot Be Used with Change Units
When a custom filter is used by a source provider to enumerate changes that contain change units, unexpected results can occur, including loss of data. Because of this, when a change that contains change units is added to a filtered change batch that uses a custom filter, the ItemChange.AddChangeUnitChange method throws SyncInvalidOperationException exception (for managed code) or ISyncChangeBuilder::AddChangeUnitMetadata returns SYNC_E_INVALID_OPERATION (for unmanaged code).
4. Documentation and Samples
a. Samples Must Be Reconfigured to Run on Non-x86 Platform
The Sync Framework samples are configured to build for the x86 platform. When Sync Framework for another platform is installed, such as for the x64 platform, the samples fail to run and throw an exception with the following message: "Retrieving the COM class factory for component with CLSID {DBFD020B-D830-4FBE-A927-566B1F57A17A} failed due to the following error: 80040154."
To fix this problem, reconfigure the sample to build for the current platform, such as the x64 platform. Rebuild the sample and it will run without errors.
b. Some API Members Are Incorrectly Documented
-
The filteringType parameter of the Microsoft.Synchronization.FilterRequestCallback delegate, of type Microsoft.Synchronization.FilteringType, is missing a description in the documentation. This parameter indicates the type of information that is included in a change batch during filtered synchronization.
-
The return value of the Microsoft.Synchronization.Data.DbSyncTableDescription.IsTableMapped property is incorrectly described in the documentation. This return value is false if the GlobalName and LocalName property values are the same; otherwise it is true.
c. IntelliSense for Chinese Traditional Displays English Text
When the Chinese Traditional version of Sync Framework 2.0 is installed, Microsoft Visual Studio 2008 displays English IntelliSense content. To fix this issue, upgrade to Visual Studio 2008 SP1.