0
votes

I'm using SQL CE 3.5, Microsoft.Synchronization.Data.SqlServerCe 3.1 and MSSQL 2008 and for every insert i catch the same exception with ApplyChangeFailed event on ServerSyncProvider.

I have got this error thrown for every insert made with synchronization: "SQL Server change tracking has cleaned up tracking information for table ''''%s''''. To recover from this error, the client must reinitialize its local database and try to synchronize again."

I got this piece of SQL when inserting row: "IF CHANGE_TRACKING_MIN_VALID_VERSION(object_id(N''[TargetMetricValue]'')) > @sync_last_received_anchor RAISERROR (N''SQL Server change tracking has cleaned up tracking information for table ''''%s''''. To recover from this error, the client must reinitialize its local database and try to synchronize again.'', 16,3,N''[TargetMetricValue]'')" and got this: "@sync_last_received_anchor=0"

CHANGE_TRACKING_MIN_VALID_VERSION(object_id(N''[TargetMetricValue]'')) returns 146113 and as it is greater than 0 the above exception is thrown.

On ServerSyncProvider class method ApplyChanges is called => serverSyncProvider.ApplyChanges(groupMetadata, dataSet, syncSession);

groupMetadata.NewAnchor = null, groupMetadata.TablesMetadata[0].LastReceivedAnchor.Anchor = null, groupMetadata.TablesMetadata[0].LastSentAnchor.Ancor = byte[]{127,35,6,0,0,0,0,0}

I bet LastReceivedAnchor is related to sync_last_received_anchor but I dont get any valid value after calling syncAgent.Synchronize()

Also on SqlCeClientSyncProvider method GetTableReceivedAnchor I get null and for GetTableSentAnchor I get value byte[]{127,35,6,0,0,0,0,0}.

So what may be missing that I get null (0) for that value?

UPDATE according to the first comment:

I have initial CE db file xyz.sdf It's connection string is declared in app.config as: 'add name="localConnection" connectionString="Data Source = |DataDirectory|\Data\xyz.sdf;Max Database Size=3968" providerName="System.Data.SqlServerCe.3.5"'

It's initialized with this code:

public SyncAgent()
    {
        systemTables = new List<string> {"__syncArticles", "__syncSubscriptions", "__syncTransactions"};
        ClientSyncProvider = new SqlCeClientSyncProvider(ConfigurationManager.ConnectionStrings["localConnection"].ConnectionString, true);
        LocalProvider = ClientSyncProvider;
        InitializeAllSyncTables();
    }
1
how did you initialize your client database? did you use the Local Database Cache Wizard to generate the Sync Fx code or did you hand code them? - JuneT
It's predefined sdf file, more details in post updates. - Aurimas Neverauskas
By any chance, have you tried increasing retention and cleanup window ? you may already have looked at social.microsoft.com/Forums/en-US/syncgeneral/thread/… and sqlmonster.com/Uwe/Forum.aspx/sql-server-ce/3911/… - Mehdi LAMRANI
Its set to 2 days, anyway two sequencial inserts gives this exception two times. I think that server should send anchor (timestamp) to client DB, but it never happens. I will try to clean table declarations in CE db and I will try to synchronize (don't know if it works this way). - Aurimas Neverauskas
@Aurimas - how are you creating or initializing the client SDF? does it contain rows already before you make it part of the sync process? - JuneT

1 Answers

0
votes

If any body still has a question how to solve this, check this post Programming Microsoft Synchronization Services for ADO.NET (Devices). This is very helpful, also batching fails for new databases as sync anchor is not found, so find a way to get the client database instantiated before you can do batching on client databases. Or downlaod the sdf file directly on the client database.

I faced same scenario, I wrote two different InitializeNewAnchorCommand() methods, one for batching and other for one shot database sync which can get my database instantiated from the code directly.

here is what I have, it worked for me.

try
{
    // Synchronize
    syncStats = syncAgent.Synchronize();
    App.SyncStats = syncStats;
}
catch (SyncException exception)
{
    if (exception.Message.Contains(" Unable to obtain a new server anchor."))
    {                    
        syncSnapShotStats = syncSnapShotAgent.Synchronize();
        App.SyncStats = syncSnapShotStats;
    }
    else
    {
        throw;
    }
}