none
Initial sync always upload all data? RRS feed

  • Question

  • Hi all, 

    I am fairly new to Sync Framework 2.1 and recently I've developed an application based on local database cache tutorial, I've however noticed when running the very first initial sync to the database it always upload almost all data back to the server, is it normal behavior for sync framework to do upload all data back to server? If not, what did I do wrong? 

    And what is the best approach for including database for my application? I mean, should I include an empty database for my users that allows them to sync back to database? or should I just include a fully loaded database with latest data in it? 

    Many thanks in advance.

    SyncOperationStatistics syncStats = null;
                SqlCeConnection clientConn = null;
                SqlConnection serverConn = null;
                try
                {
                    ProvisionServerDatabase();
                    ProvisionClientDatabase();
    
                    clientConn = new SqlCeConnection(Properties.Settings.Default.ClientConnectionString);
                    serverConn = new SqlConnection(Properties.Settings.Default.ServerConnectionString);
    
                    // create the sync orhcestrator
                    SyncOrchestrator syncOrchestrator = new SyncOrchestrator();
                    syncOrchestrator.LocalProvider = new SqlCeSyncProvider(DBScopeName, clientConn);
                    syncOrchestrator.RemoteProvider = new SqlSyncProvider(DBScopeName, serverConn);
                    //((SqlCeSyncProvider)syncOrchestrator.LocalProvider).ApplyChangeFailed += new EventHandler<DbApplyChangeFailedEventArgs>(Program_ApplyChangeFailed);
    
                    if (Program.appconfig.UserRole == (int)ClassModules.UserRoles.ReadOnly)
                    {
                        // set the direction of sync session to Download
                        syncOrchestrator.Direction = SyncDirectionOrder.Download;
                    }
                    else
                    {
                        // set the direction of sync session to Upload and Download
                        syncOrchestrator.Direction = SyncDirectionOrder.UploadAndDownload;
                    }
    
                    // execute the synchronization process
                    syncStats = syncOrchestrator.Synchronize();
    
                    return syncStats;
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    if (clientConn != null)
                    {
                        clientConn.Close();
                        clientConn.Dispose();
                    }
    
                    if (serverConn != null)
                    {
                        serverConn.Close();
                        serverConn.Dispose();
                    }
                }

    Thursday, June 14, 2012 7:42 AM

Answers

  • from the looks of your code, its not from the Local Database Cache wizard.

    when you provision, do you have existing data on your client database that is the same data in the server?

    if both client and server database have the same data when you provision, sync fx has no idea the data are one and the same.

    so even if your client's data is the same as the server, it will upload it and will consequently result to conflicts.

    if you want to distribute a  preloaded client database, use the GenerateSnapshot approach to create a snapshot sdf that you can distribute. each peer in sync fx has a unique id to identify it in the sync community, if you copy an sdf from one client to another, you now have two clients having the same replica id. the generate snapshot approach makes sure the replica id is adjusted on first use.

    • Marked as answer by Louis987789 Friday, June 15, 2012 12:30 AM
    Thursday, June 14, 2012 7:52 AM
    Moderator
  • the _tracking tables are used by Sync Fx to determine which rows has changed. if you look at the tables you are synching, they have triggers for insert/update/delete that update the _tracking tables.

    if you're client has pre-existing data and your sync direction is UploadAndDownload, then sync fx will upload the existing rows from your client.

    are you trying to prevent sync fx from uploading existing rows on the client?

    you can distribute an empty database, but that means your initial sync will be slower as it needs to sync rows to the empty client database.

    • Marked as answer by Louis987789 Friday, June 15, 2012 12:30 AM
    Thursday, June 14, 2012 10:17 AM
    Moderator

All replies

  • from the looks of your code, its not from the Local Database Cache wizard.

    when you provision, do you have existing data on your client database that is the same data in the server?

    if both client and server database have the same data when you provision, sync fx has no idea the data are one and the same.

    so even if your client's data is the same as the server, it will upload it and will consequently result to conflicts.

    if you want to distribute a  preloaded client database, use the GenerateSnapshot approach to create a snapshot sdf that you can distribute. each peer in sync fx has a unique id to identify it in the sync community, if you copy an sdf from one client to another, you now have two clients having the same replica id. the generate snapshot approach makes sure the replica id is adjusted on first use.

    • Marked as answer by Louis987789 Friday, June 15, 2012 12:30 AM
    Thursday, June 14, 2012 7:52 AM
    Moderator
  • Hi June,

    Thanks for timely reply, you were right about the code wasn't generated from Local Database Cache wizard as I have giving up on it and moved on to framework 2.1 for obvious reasons.

    The existing data on the client database is not the same data in the server as the server updates the data constantly by other application.

    On a closer inspection of my server database, I've noticed there are couple more tables were created for tracking and each one of them contains data, could it be the uploads from client side? or was the provisioning?

    As for the distribution of database, can I include an empty database with tables already created? 

    Below is my code for Provision both client and server database.

    Thanks for your replies.

    public static void ProvisionServerDatabase()
            {
                SqlConnection serverConn = null;
    
                try
                {
                    serverConn = new SqlConnection(Properties.Settings.Default.ServerGotechConnectionString);
    
                    DbSyncScopeDescription scopeDesc = new DbSyncScopeDescription(DBScopeName);
                    SqlSyncScopeProvisioning serverConfig = new SqlSyncScopeProvisioning(serverConn);
    
                    if (!serverConfig.ScopeExists(DBScopeName))
                    {
                        //SqlSyncScopeDeprovisioning clientSqlDepro = new SqlSyncScopeDeprovisioning(serverConn);
                        //clientSqlDepro.ScriptDeprovisionScope(DBScopeName);
                        //clientSqlDepro.DeprovisionScope(DBScopeName);
    
                        DbSyncTableDescription tableDescProduct_Opts = SqlSyncDescriptionBuilder.GetDescriptionForTable("Product_Opts", serverConn);
                        DbSyncTableDescription tableDescProducts = SqlSyncDescriptionBuilder.GetDescriptionForTable("Products", serverConn);
                        DbSyncTableDescription tableDescSystem_Opts = SqlSyncDescriptionBuilder.GetDescriptionForTable("System_Opts", serverConn);
                        DbSyncTableDescription tableDescUsers = SqlSyncDescriptionBuilder.GetDescriptionForTable("Users", serverConn);
    
                        scopeDesc.Tables.Add(tableDescSystem_Opts);
                        scopeDesc.Tables.Add(tableDescUsers);
                        scopeDesc.Tables.Add(tableDescProducts);
                        scopeDesc.Tables.Add(tableDescProduct_Opts);
    
                        //note that it is important to call this after the tables have been added to the scope
                        serverConfig.PopulateFromScopeDescription(scopeDesc);
    
                        //indicate that the base table already exists and does not need to be created
                        serverConfig.SetCreateTableDefault(DbSyncCreationOption.Skip);
    
                        serverConfig.UserComment = Program.appconfig.GT_AliasName;
    
                        //provision the server
                        serverConfig.Apply();
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    if (serverConn != null)
                    {
                        serverConn.Close();
                        serverConn.Dispose();
                    }
                }
            }
    
            public static void ProvisionClientDatabase()
            {
                SqlCeConnection clientConn = null;
                SqlConnection serverConn = null;
    
                try
                {
                    // create a connection to the SyncCompactDB database
                    clientConn = new SqlCeConnection(Properties.Settings.Default.ClientGotechConnectionString);
    
                    // create a connection to the SyncDB server database
                    serverConn = new SqlConnection(Properties.Settings.Default.ServerGotechConnectionString);
    
                    // create CE provisioning object based on the ProductsScope
                    SqlCeSyncScopeProvisioning ceConfig = new SqlCeSyncScopeProvisioning(clientConn);
    
                    if (!ceConfig.ScopeExists(DBScopeName))
                    {
                        //SqlSyncScopeDeprovisioning clientSqlDepro = new SqlSyncScopeDeprovisioning(serverConn);
                        //clientSqlDepro.ScriptDeprovisionScope(DBScopeName);
                        //clientSqlDepro.DeprovisionScope(DBScopeName);
    
                        DbSyncScopeDescription scopeDesc = SqlSyncDescriptionBuilder.GetDescriptionForScope(DBScopeName, serverConn);
                        ceConfig.PopulateFromScopeDescription(scopeDesc);
                        ceConfig.SetCreateTableDefault(DbSyncCreationOption.CreateOrUseExisting);
                        ceConfig.Apply();
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    if (clientConn != null)
                    {
                        clientConn.Close();
                        clientConn.Dispose();
                    }
    
                    if (serverConn != null)
                    {
                        serverConn.Close();
                        serverConn.Dispose();
                    }
                }
            }


    • Edited by Louis987789 Thursday, June 14, 2012 8:52 AM adding source codes
    Thursday, June 14, 2012 8:51 AM
  • I forgot to mention I have tried Deprovisioning and even PerformPostRestoreFixup but none of the method can help in reduce the initial uploading, and also after the first initial upload the second sync will perform normally without any uploads, any idea?

    Thursday, June 14, 2012 8:58 AM
  • the _tracking tables are used by Sync Fx to determine which rows has changed. if you look at the tables you are synching, they have triggers for insert/update/delete that update the _tracking tables.

    if you're client has pre-existing data and your sync direction is UploadAndDownload, then sync fx will upload the existing rows from your client.

    are you trying to prevent sync fx from uploading existing rows on the client?

    you can distribute an empty database, but that means your initial sync will be slower as it needs to sync rows to the empty client database.

    • Marked as answer by Louis987789 Friday, June 15, 2012 12:30 AM
    Thursday, June 14, 2012 10:17 AM
    Moderator
  • Hi June,

    Many thanks for all your clearly explanations, much appreciated!

    Is there a way to stop client uploading existing rows to server at the initial sync after distribute the application with loaded database to client? I have tried to use sync direction (Download) at the initial sync then changed to (UploadAndDownload) after first sync and it still uploads all existing rows back to server, why does it do that? shouldn't it stop uploading rows on the second sync as all rows should updated to server version?

    Friday, June 15, 2012 12:46 AM
  • i suggest you enable sync fx tracing so you have more information on what is happening.

    Sunday, June 17, 2012 12:54 PM
    Moderator