locked
Sync framework on upload reporting sync conflicts but does not fire remote provider ApplyChangesFailed event RRS feed

  • Question

  • Hello all... looking to see if anyone has experienced this situation with sync fx. 

    I have problem on one of my scopes that is getting uploaded to the remote server which is on the same domain.

    When doing an upload sync the orchestrator reports that there are upload failures in the sync result but it never fires the ApplyChangesFailed event.  The whole result set that is being synced up is about 2000 rows on a lookup table - out of that set I get about 130 failures, but I can't find out what is failing because the event never fires, and therefore can't resolve. If I do another sync these 130 failures are still there as I have no way to say ignore them in the conflict resolution.

    Is there something I'm missing here.  If I have failures I still should get the apply changes event to fire from the remote provider?  Is there a way I can diagnose what is going on here.  Thanks in advance.

    Friday, March 8, 2013 4:37 AM

All replies

  • can you post the snippet where you're binding the event handler for ApplyChangeFailed event as well the event handler itself?

    Friday, March 8, 2013 6:55 AM
  • here it is... let me know if you need more.

    This is where it attaches the event handler:

     SyncOrchestrator orchestrator = new SyncOrchestrator();
    
     orchestrator.LocalProvider = localSyncProv;
     orchestrator.RemoteProvider = remoteSyncProv;
     orchestrator.Direction = syncOrder;
                
    ((RelationalSyncProvider)orchestrator.LocalProvider).ApplyChangeFailed += new EventHandler<DbApplyChangeFailedEventArgs>(LocalProvider_ApplyChangeFailed);
                
    ((RelationalSyncProvider)orchestrator.RemoteProvider).ApplyChangeFailed += new EventHandler<DbApplyChangeFailedEventArgs>(RemoteProvider_ApplyChangeFailed);
    
    SyncOperationStatistics stats = orchestrator.Synchronize();
    

    Here is where I handle the conflicts:

    private void RemoteProvider_ApplyChangeFailed(object sender, DbApplyChangeFailedEventArgs e)
    {
    	this.LogConflictData(e);
    	
    	if (e.Conflict.Type == DbConflictType.ErrorsOccurred)
    	{
    		e.Action = ApplyAction.Continue;
    		return; 
    	}
    
    	e.Action = ApplyAction.RetryWithForceWrite;
    	
    }

    Right now I'm not doing a whole lot of conflict resolution.  I want to see what records failed on the table and then try and see how to handle the errors.

    What I'm thinking is going on is the

    SyncOperationStatistics stats 

    is reporting back erroneous failures when there really wasn't any, but I can't see what the errors are that it is reporting.  Is there a way to see those errors when the conflict resolution event doesn't fire from the sync provider?  Thanks for your help, it is greatly appreciated!!


    Friday, March 8, 2013 4:05 PM
  • Further info - after doing a trace and looking at the log when I look at the particular scope and table that is causing the problem here is what the log states

    INFO   , xxx.vshost, 30, 03/08/2013 17:03:29:338,    ----- Inserts for Table "xxxxxx" -----
    ERROR  , xxx.vshost, 30, 03/08/2013 17:03:29:647, Change Application failed due to Row Metadata not Found
    INFO   , xxx.vshost, 30, 03/08/2013 17:03:29:649,       131 Inserts Applied
    INFO   , xxx.vshost, 30, 03/08/2013 17:03:29:649,    --- End Inserts for Table "xxxxxx" ---
    INFO   , xxx.vshost, 30, 03/08/2013 17:03:29:649,
    ERROR  , xxx.vshost, 30, 03/08/2013 17:03:29:650, Rolling back transaction

    Could the row metadata error be causing my issue and how can I solve this issue or see what is causing it?  Thanks a lot.

    Friday, March 8, 2013 5:37 PM
  • can you confirm if you have rows in your table that has no corresponding rows in the _tracking tables? are you doing bulk inserts via bcp or other methods that dont fire triggers?
    Saturday, March 9, 2013 1:38 AM
  • JuneT thanks for all the feedback....

    In the current test that I am doing with data I have a database locally that is copy of the server.  It has been provisioned with all the relative scope and tracking info.  For the particular table that is causing the problems the only things that should have been applied are inserts.  This table is actually the only table in this scope.  When inspecting the tracking table there are corresponding records for those inserts.  There are no deletes (tombstone records) in the table.  This is on the local side.  I have compared the data in the tracking table to data in the source table and there are corresponding records. 

    I also hooked to the applying changes event on the local provider to see what changes are getting selected in the data set and then did a query to the tracking table to see if there was not a record for that change selection, and I did not get any mismatches.

    Is there another way I can see all the change selections for that scope and the table that are going to be applied to the Remote.

    In a related note could you shortly explain to me how the syncing system enumerates changes for a particular scope on a table? Maybe I am missing something in the understanding as how it selects the change it needs to apply.     Thanks for all your help.

    Monday, March 11, 2013 1:41 AM
  • in an upload scenario, you should subscribe to the ChangesSelected event of the local provider to verify the changes being selected and ApplyingChanges on the remote provider to confirm the changes to be applied.

    you mentioned your local database is a copy of the server, did you make the copy after you provisioned the server database? did you do a PerformPostRestoreFixup when you after you restored on the client?

    Monday, March 11, 2013 10:50 AM
  • It is a copy of the server's base table data through a script and does not contain any sync information.  I then provision this local database, make some local changes and sync it to the server in order to test.

    I have used PerformPostRestoreFixup in the past but I would always get an error thrown when I used that method.  The thrown error  would display this message: The SqlTransaction has completed; it is no longer usable.

    Can you explain what the this method  is actually supposed to do? 

    I'm sorry for all the questions, but it seems I have hit a brick wall.

    Monday, March 11, 2013 2:52 PM
  • if your client contains the same data as the server, unless you have a filter on the client side, your upload will upload all rows from your client including those that already exists on the server thus causing conflicts to get fired.

    The PerformPostRestoreFixup processes the metadata so you can keep the knowledge of what was previously synched and correspondingly, give the newly restore database a new replica id. If you don't do the PerformPostRestoreFixup, you'll have replicas having the same Id which will cause issues with sync. I've never run into the SqlTransaction error when doing the restore fixup.


    Tuesday, March 12, 2013 11:35 AM