locked
How to refresh updated but not synchronized rows? RRS feed

  • Question

  • Hello,

    my environment is a MS SQL Server Application and several windows mobile 2005/6.1 clients with SqlCe.

    I´ve a problem with the Exception handling, if a ApplyChangedFailed event occurs:

                this.ApplyChangeFailed += new System.EventHandler<Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs>(EtaskLocalDataCacheServerSyncProvider_ApplyChangeFailed);


    If this happens, my changes where not stored at the Server, because an error occurred, which is clear for me. My question is now, what I can do to refresh the not-synchrized rows where the error occured to make it possible to synchronize them with the next synchronization process.

    At the moment, the rows where an error occurred are not synchronized again during the next synchronization process. I guess it is because the MS Sync Framework uses some functionality of the SqlCE Server which marks changed and added database rows. Can this be true?


    Does anybody know a good tutorial which handles these problems?


    Regards,

    Martin


    • Moved by Hengzhe Li Friday, April 22, 2011 5:23 AM (From:SyncFx - Microsoft Sync Framework Database Providers [ReadOnly])
    Tuesday, March 10, 2009 1:49 PM

Answers

  • This is what I got after reading your post -

    Some change apply error occures during upload stage (from SQL CE to SQL server) and the changed rows were not applied on the server.  You would like to find a way to re-enumerate all previous changes in the next sync, right?

    If this is right, one work around is - collecting the PrimaryKey (or other sync identity) of these failed rows and after sync, do dummy update on these rows on the SQL CE side, such as

    Update t1 set column1 = column1 where pid in [...]

    Thanks.
    Leo Zhou ------ This posting is provided "AS IS" with no warranties, and confers no rights.
    Tuesday, March 10, 2009 5:16 PM
    Answerer

All replies

  • This is what I got after reading your post -

    Some change apply error occures during upload stage (from SQL CE to SQL server) and the changed rows were not applied on the server.  You would like to find a way to re-enumerate all previous changes in the next sync, right?

    If this is right, one work around is - collecting the PrimaryKey (or other sync identity) of these failed rows and after sync, do dummy update on these rows on the SQL CE side, such as

    Update t1 set column1 = column1 where pid in [...]

    Thanks.
    Leo Zhou ------ This posting is provided "AS IS" with no warranties, and confers no rights.
    Tuesday, March 10, 2009 5:16 PM
    Answerer
  • Hello Leo,

    yes you have understood right. That is exactly my problem.
    But I think your solution is not very "clean" because you can get dirty reads/writes.


    Imagine you have one server S and two clients A and B



    A changes a datarow at time t1.
    B changes a datarow at time t2 with t2=t1+1hour

    So Client B has a newer(!)  datarow

    Now... one day ago both clients want to sync with the server.

    Client A starts syncing and the sync process fails.
    With your solution, the datarow of Client A with t1 will get a newer timestamp because of the dummy update. lets say t1=t1+1day

    Then Client B syncs to the server and the sync process was fine => the updated dataset is stored to the server S.

    Now A tries another sync. The sync was fine and the data stored on the server, because timestamp t1 is now newer than t2.
    But this happens only because of your dummy update, otherwise the dataset would be rejected because it´s too old.



    I hope you understand what I mean?

    Please let me know if not and I will try to find a way to make it clearer.



    But in general.... how do you handle the problems if an ApplyChanges failed?
    I think it´s maybe a big bug in the MS Sync Framework Code or Concept(?) because the datasets in the client database should
    only be marked as "not new" or "not updated" if the sync process was finished without any problems.



    Regards,

    Martin
    Wednesday, March 11, 2009 6:11 PM
  • Each client has its own local timestamp to mark as a sent anchor after every sync.  
    Let us say on Client A, one row R was failed to upload in the last sync.  When last sync completes, assume 10 was the local timestamp so 10 is used as the last sync anchor by the local store A.  Since R was failed, we do a dummy update which bumps R's update version to be 11 (> 10, the last sent anchor).  In the next sync, local store enumrates all changes > 10.  Therefore R is enumerated during a change detection.

    More, if a client is doing bi-directional sync, it also "remembers" the another anchor value, received from the Server.  Meaning it got all server's change up to the latest server's timestamp.

    This is what I understanding about your second example.

    Client A downloads row R and Client B downloads the same row R.
    A made a change and B made a later change  than A did.

    At this moment, Server has a timestamp of X, A has a timestamp of 10, (do not care of B).

    Now Client A do sync.  R is failed to upload to S (for some reason).  No change on Server.  X is still the latest timestamp on S.  After sync, X is received on A, meaning it gets all server's change up to timestamp X.  Since R is failed to upload so we do a dummy update on Client A, R'scurrent version bumps to 11.

    B tried to upload its change of R to Server and passed.  At this moment, on S, its timestamp bumps to X+1.  R's current version on S goes to X+1.

    Client A sync with S again.  Since R's current version on A is 11 > 10, this change is enumerated and sent to server.  However it can not applied because R's current version on S is X+1 (> X), meaning R has newer changes than A knows about (because A only knows changes from S up to X).  The sync actually encounters a Update/Update concurrency conflict.  And usually a sync application should handle this kind of conflict in the ChangeApplyFailed event from the server provider.

    Thanks,

    Leo Zhou ------ This posting is provided "AS IS" with no warranties, and confers no rights.
    Wednesday, March 11, 2009 8:15 PM
    Answerer
  • Hello Leo,


    ok thank you. I begin to understand.The  MS Sync Framework uses logical clocks.
    Is there a special reason why you use logical clocks?

    You said the clients use local timestamps, means e.g. getdate() on the SQL Server.
    But you could only use the UTC date with getutcdate() in general for all clients. So all clients would have the same datetime and
    not a local timestamp.

    Of course... there could be the problem that the client time is set wrong or not configured but e.g. you can also
    sync times with the before starting the sync process.

    E.g. deltaTime = [UTCDateServer] - [UTCDateClient]

    so every timestamp comparison also considers the delta time.


    E.g. the comparison would be:


    if([UTCTimeStamp Server] - ([UTCDateServer] - [UTCDateClient])> [UTCTimeStamp Client])

    => conflict!!!

    else

    => no conflict!!!


    This concept of course also has a big problem:
    "what happens when the client changes it´s local time (e.g. from winter to summer time) between two synchronization processes?"


    All in all.... is there maybe a way to change the syncing to a UTC timestamp or are there any future plans to provide such functionality?

    Or much better .... a concept to code your own conflict detection function?
    This would be the cleanest solution for a Sync Framework in my opion. To use a standard conflict detection function but provide ways
    to override these functions/classes with self-written code.



    Pleease do not think that I want to call the whole Sync Framework into question. I am only asking because of personal interests and because I think that a server-synched- UTC-Date conflict detection would be better for my kind of application.



    Regards from Cologne,

    Martin
    Thursday, March 12, 2009 8:52 AM
  • I thought about the logical clock solution yesterday and now I think, that this would be also a good solution for my projekt.

    The only thing I do not like is that I have to make an dummy-update when ApplyChangesFailed.
    Because if a client really has big problems he will always win with his changes, because he made several dummy updates.

    So isn´t there any other solution for that?


    Friday, March 13, 2009 10:23 AM