locked
Demo IV: Offline Application – Conflict Handling RRS feed

  • Question


  • Hi all,

    I just posted the forth demo in the series. This demo extends the previous demos and adds conflict handling logic. Conflicts are fact of life in occasionally connected synchronization scenarios. As a sync developer, you need to find a way to deal with this type of changes that if applied without too much thought will lead to data loss and unhappy customers. Synchronization Services for ADO.NET provides the necessary infrastructure to enable you to detect, surface and resolve conflicts. In this demo, I show you how to register to receive conflict events, dissect the information in SyncConflict object and surface it to the user, and the different options to resolve each conflict.

    I encourage you to read the full description of the demo on my blog: http://blogs.msdn.com/synchronizer/archive/2007/02/07/demo-iv-offline-application-conflict-handling.aspx

    To download the demo directly: http://blogs.msdn.com/synchronizer/attachment/1615465.ashx

    Thanks

    • Moved by Max Wang_1983 Friday, April 22, 2011 8:20 PM forum consolidation (From:SyncFx - Microsoft Sync Framework Database Providers [ReadOnly])
    Wednesday, February 7, 2007 1:43 AM

All replies

  • Hi Rafik,

    This demo looks really good and I have to admit that I am new to all of this so I apologize if this is obvious.  I can not tell from this if you have access to the "before" value of the update.  For some conflict resolution I want to be able to handle the update based on the value it was previously.  Can you tell me if that is possible?
    Friday, February 9, 2007 7:11 PM
  • Interesting!

    This seems to be a store feature and not sync feature. For example, your store could have a history of all changes that happen to a given row or maybe just the last change. If this is the case, then your SelectUpdatedConflictRows and SelectDeletedConflictRows commands can be written in such a way to return the current conflict row along with the available history of changes. Your conflict event handler can then use this history to decide how to resolve the conflict.

    You can implement this history feature yourself using triggers for example. The point is, if you have the information, you can surface it through Sync Services APIs.

    The SQLCE sync provider does not capture old changes and thus cannot surface any “before update” information.

    Thanks

    Friday, February 9, 2007 10:16 PM
  • Hi Rafik,

    Could you explain why in your applyupdate stored procedure
    under -- force write resolution option there is no where clause for the update statement?

    Thanks.

    Friday, February 16, 2007 6:41 PM
  • Hi Alekesy

    The normal course of action is that I will update the row with the client change if there was no change to the row since the last time the client synchronized. This is what the where clause does, as you see below

    update [orders]
         set [order_date] = @order_date,
             [update_originator_id] = @sync_client_id_hash
         where (update_timestamp <= @sync_last_received_anchor or update_originator_id = @sync_client_id_hash) and [order_id] = @order_id


    Now if this condition was not met, a conflict is detected and surfaced to the developer through the ApplyChangeFailedEvent. The runtime gives you the hooks needed to tell you what the user wants to do with this conflict. The sync runtime does not implement that logic though, for "client wins" resolution option, it just flips the @sync_forcewrite variable and pass it to your update command.

    In the demo, when the force write flag is set, I just overrite the existing row. The where clause is not needed anymore.

    Friday, February 16, 2007 7:52 PM
  • Hi Rafiq,


    I had gone through the samples you had provided, and that really helps.

    But I have DB2 at server end and hence I am facing many problems, please see if you can answer my query.

    "I am using DB2 on server and SQL CE on client and we are not able to perform the sync using Microsoft Synchronization Services, though the code work fine with SQL server at server end.

    We had tried with OLEDB and DB2 Data provider, with OLEDB we are able to insert one row in table but all continuous insert operations are failed and no update or delete is working.

    With DB2 data provider we are able to connect to database but when we are trying to provide connection to sync service provider it is throwing an exception ": Invalid connection object. Unable to create a new instance of the connection object"

     

    Regards

    Sachin

    Wednesday, March 14, 2007 6:11 AM
  • Hi,

    I was also wondering about the missing where clause and I too think, that it is needed. I had five rows on the client and server and made an update-update conflict in one row (year 2007 on client an 2006 on server). I chose ForceWrite and now the datetime from the client (12.11.2007 15:34) was not only inserted in the one row but in all five (also in the four which where not updated). From now on, Client and Server where not in Sync, since client had 2005 in one row and the server has now 2007 in every row.

    After inserting the where-clause everything worked fine. I had the same problem in order_details.

     

    Code Block

    create procedure dbo.sp_orders_applyupdate (   

                @sync_last_received_anchor binary(8) ,

                @sync_client_id_hash int ,

                @sync_force_write int,

                @sync_row_count int out,

            @order_id int,

            @order_date datetime = NULL )       

    as         

          update [orders]

              set [order_date] = @order_date,

                  [update_originator_id] = @sync_client_id_hash

              where (update_timestamp <= @sync_last_received_anchor or update_originator_id = @sync_client_id_hash) and [order_id] = @order_id

          set @sync_row_count = @@rowcount

         

          -- force write resolution option

          if @sync_row_count = 0 and @sync_force_write = 1

          begin

              update [orders]

                  set [order_date] = @order_date,

                  [update_originator_id] = @sync_client_id_hash

                      where [order_id] = @order_id  

              set @sync_row_count = @@rowcount     

          end  

    go

     

     

     

    Monday, November 12, 2007 2:45 PM
  • Hi,

     

    When I try to compile the project, I get a number of errors:

     

    Error 1 The type or namespace name 'SyncTable' could not be found (are you missing a using directive or an assembly reference?) C:\Users\irvinem\Documents\Visual Studio 2005\Projects\OfflineAppDemo-Conflicts\app\SyncForm.cs 106 17 OfflineAppDemo-Conflicts

    Error 3 The name 'TableCreationOption' does not exist in the current context C:\Users\irvinem\Documents\Visual Studio 2005\Projects\OfflineAppDemo-Conflicts\app\SyncForm.cs 107 46 OfflineAppDemo-Conflicts

    Error 4 'Microsoft.Synchronization.SyncDirection' does not contain a definition for 'Bidirectional' C:\Users\irvinem\Documents\Visual Studio 2005\Projects\OfflineAppDemo-Conflicts\app\SyncForm.cs 108 59 OfflineAppDemo-Conflicts

    Error 12 'Microsoft.Synchronization.SyncAgent' does not contain a definition for 'Configuration' C:\Users\irvinem\Documents\Visual Studio 2005\Projects\OfflineAppDemo-Conflicts\app\SyncForm.cs 125 27 OfflineAppDemo-Conflicts

     

    I downloaded the sync framework and sync service for ado.net from the microsoft site (msdn.microsoft.com/sync).

     

    Has anyone else experience this problem?  Or have I just not done something very simple?

     

    Mark

     

    Tuesday, November 13, 2007 12:49 PM
  • Are you using VS 2005 or VS 2008?

    Tuesday, November 13, 2007 1:42 PM
  • Hi,

     

    Sorry forgot to include that info - I'm using VS 2005.

     

    Thanks,

     

    Mark

     

    Tuesday, November 13, 2007 1:44 PM
  • Hi Mark

     

    You have downloaded the Microsoft Sync Framework which ships the v2 of Sync Services for ADO.NET. We made changes to the Sync Services to better fit with the framework thus you are hitting these compilation erros with the samples that was intended for sync services v1.

     

    If you want to get V1 bits of sync services, you can downlaod it from here

    If you want samples for v2 CTP, then it should be part of the package you downloaded.

     

    Thanks

     

    Tuesday, November 13, 2007 5:00 PM
  • Hi Christine,

     

    You are right, the where clause is definitely missing. I will check the sample and fix it.

    See, since you can write the sync commands you could spot any issues and fix them yourself. Isn't that cool?

     

    Thanks

     

    Tuesday, November 13, 2007 5:03 PM
  •  

    I have also noticed that in demo.sql the order_details update trigger updates the orders table:

     

    CREATE TRIGGER order_details_update_trigger on order_details for update

    as

    declare @key int

    select @key = order_id from inserted

    if not UPDATE(update_originator_id)

    update orders set update_originator_id = 0 where order_id = @key

    go

     

    shouldn't it be:

     

    CREATE TRIGGER order_details_update_trigger on order_details for update

    as

    declare @key int

    select @key = order_id from inserted

    if not UPDATE(update_originator_id)

    update order_details set update_originator_id = 0 where order_id = @key

    go

    Monday, December 10, 2007 8:52 PM
  •  

    Thanks Stephanie,

     

    You are right, the trigger should update the Order_details table, not the Orders table. this caused some data cahnges on the order details not sent to the clients.

     

    Thanks again for catching this up.

     

    Regards.

    Yunwen

    Friday, January 18, 2008 12:48 AM
    Moderator
  •  

    Stephanie,

     

    This bug has been fixed.  Thanks for bringing this to our attention.

     

    Sean Kelley

    Microsoft

    Program Manager

    Thursday, March 20, 2008 10:31 PM
    Moderator