none
Mobile Services - Sync - Conflict Resolution RRS feed

  • Question

  • catch (MobileServicePushFailedException exc)
                {
                    if (exc.PushResult != null)
                    {
                        await TicketsResolveConflictsAsync(exc.PushResult.Errors).ConfigureAwait(false);
                    }
                }
    
    
    
            private async Task TicketsResolveConflictsAsync(ReadOnlyCollection<MobileServiceTableOperationError> syncErrors)
            {
                foreach (var error in syncErrors)
                {
                    Debug.WriteLine($"Conflict during update: Item: {error.Item}");
    
                    var serverItem = error.Result.ToObject<Tickets>();
                    var localItem = error.Item.ToObject<Tickets>();
    
                    localItem.Version = serverItem.Version;
                    await error.UpdateOperationAsync(JObject.FromObject(localItem)).ConfigureAwait(false);
                }
            }

    If I want to handle conflict resolution inline with syncing and I always want to default to restoring the local copy is this the proper way to do that?  I really want the client to always win.
    Wednesday, June 29, 2016 5:45 PM

Answers

All replies

  • Your code looks basically correct.  I've got some working code that does exactly this here: https://github.com/adrianhall/30-days-of-zumo-v2/blob/master/blog-code/Client.UWP/Services/AzureDataTable.cs#L112

    Wednesday, June 29, 2016 6:16 PM
    Moderator
  • If you want the client to always win, then you can just remove the Version field from your client data model. Then, all updates from the client will succeed.
    Wednesday, June 29, 2016 8:39 PM
    Moderator
  • If you want the client to always win, then you can just remove the Version field from your client data model. Then, all updates from the client will succeed.
    Great.  I think that works in our scenario.  So just to verify if we remove the Version field from client data we would remove any special handling of the MobileServicePushFailedExceptions and just handle general exceptions?
    Wednesday, June 29, 2016 9:16 PM
  • You won't get any precondition failed exceptions, but you can still end up in situation where you get a 409 conflict exception. That can happen if you client sends an insert that is sent successfully, but the response is lost due to a poor connection. The client thinks that the Insert failed and will try again, and the server will send back a MobileServiceConflictException because the client is trying to insert a value with the same primary key. That exception will still be wrapped as a MobileServicePushFailedException. I a 500 error will also be wrapped, but not network errors.

    FYI, you don't need a sync handler to handle these cases, just a regular exception handling block, as in this sample: https://github.com/lindydonna/xamarin-forms-offline-sync/blob/master/XamarinFormsOffline/TodoItemManager.cs#L117


    Wednesday, June 29, 2016 9:46 PM
    Moderator
  • You won't get any precondition failed exceptions, but you can still end up in situation where you get a 409 conflict exception. That can happen if you client sends an insert that is sent successfully, but the response is lost due to a poor connection. The client thinks that the Insert failed and will try again, and the server will send back a MobileServiceConflictException because the client is trying to insert a value with the same primary key. That exception will still be wrapped as a MobileServicePushFailedException. I a 500 error will also be wrapped, but not network errors.

    FYI, you don't need a sync handler to handle these cases, just a regular exception handling block, as in this sample: https://github.com/lindydonna/xamarin-forms-offline-sync/blob/master/XamarinFormsOffline/TodoItemManager.cs#L117


    Thanks.  So just to be sure if I am wrapping the call already in try/catch general exception handling and the 409 exceptions occurs would everything then be status quo and it won't continue trying to send that record?  Or do I have to handle that specific case and cancel/discard that operation?

    Wednesday, June 29, 2016 10:06 PM
  • If you have a PushFailed exception, then you still need to resolve the errors. Otherwise, the SDK will try to send the operation next time. You can just use the simple conflict handling in the sample above.
    Thursday, June 30, 2016 12:49 AM
    Moderator