none
Last writer wins example on using SyncOrchestrator.Synchronize() based last_change_timestamp. How to retrieve the last_change_datetime? RRS feed

  • Question

  • Hi all,

    Was looking at the sample given on how to solve the data conflict when using syncfx.

    This is the source code given in the sample to handle the event when conflict is detected during synchronization.

    private void dbProvider_ApplyChangeFailed(object sender, DbApplyChangeFailedEventArgs e) { //For conflict detection, the "local" database is the one at which the //ApplyChangeFailed event occurs. We determine at which database the event //fired and then compare the name of that database to the names of //the databases specified as the LocalProvider and RemoteProvider. string DbConflictDetected = e.Connection.Database.ToString(); string DbOther; DbOther = DbConflictDetected == _localProviderDatabase ? _remoteProviderDatabase : _localProviderDatabase; Console.WriteLine(String.Empty); Console.WriteLine("Conflict of type " + e.Conflict.Type + " was detected at " + DbConflictDetected + "."); if (e.Conflict.Type == DbConflictType.LocalUpdateRemoteUpdate) { //Get the conflicting changes from the Conflict object //and display them. The Conflict object holds a copy //of the changes; updates to this object will not be //applied. To make changes, use the Context object. DataTable conflictingRemoteChange = e.Conflict.RemoteChange; DataTable conflictingLocalChange = e.Conflict.LocalChange; int remoteColumnCount = conflictingRemoteChange.Columns.Count; int localColumnCount = conflictingLocalChange.Columns.Count; Console.WriteLine(String.Empty); Console.WriteLine(String.Empty); Console.WriteLine("Row from database " + DbConflictDetected); Console.Write(" | "); //Display the local row. As mentioned above, this is the row //from the database at which the conflict was detected. for (int i = 0; i < localColumnCount; i++) { Console.Write(conflictingLocalChange.Rows[0][i] + " | "); } Console.WriteLine(String.Empty); Console.WriteLine(String.Empty); Console.WriteLine(String.Empty); Console.WriteLine("Row from database " + DbOther); Console.Write(" | "); //Display the remote row. for (int i = 0; i < remoteColumnCount; i++) { Console.Write(conflictingRemoteChange.Rows[0][i] + " | "); } //Ask for a conflict resolution option. Console.WriteLine(String.Empty); Console.WriteLine(String.Empty); Console.WriteLine("Enter a resolution option for this conflict:"); Console.WriteLine("A = change from " + DbConflictDetected + " wins."); Console.WriteLine("B = change from " + DbOther + " wins."); string conflictResolution = Console.ReadLine(); conflictResolution.ToUpper(); if (conflictResolution == "A") { e.Action = ApplyAction.Continue; } else if (conflictResolution == "B") { e.Action = ApplyAction.RetryWithForceWrite; } else { Console.WriteLine(String.Empty); Console.WriteLine("Not a valid resolution option."); } } }

    In the sample, the conflict is resolved by asking user what kind of action to take, but what I want to perform is to compare the last write time in both remote and local db, and apply ApplyAction.RetryWithForceWrite if the row in db to be written is written at earlier time than the source.

    However, in the datatable

    DataTable conflictingRemoteChange = e.Conflict.RemoteChange

    I am not able to find the field that stated the last change datetime, so I want to know which stored procedures generated by the framework/ additional code that I have to add in to my program to retrieve this information, so that I can know whether to apply the changes to database.

    Many thanks in advance!



    Monday, October 1, 2012 9:21 AM

Answers

  • simpliest way is to add a datetime field to your table to record the the last update time then include that column in the scope.
    • Marked as answer by JacelynC Wednesday, October 3, 2012 3:30 AM
    Tuesday, October 2, 2012 1:26 AM
    Moderator

All replies

  • simpliest way is to add a datetime field to your table to record the the last update time then include that column in the scope.
    • Marked as answer by JacelynC Wednesday, October 3, 2012 3:30 AM
    Tuesday, October 2, 2012 1:26 AM
    Moderator
  • Hi June,

    Thanks for your answer. I am just wondering if we can use the last_change_datetime in the generated tblname_tracking, since it is there, and it will be more accurate because it will be updated everytime changes are made? And can I say there is no such method in syncfx that i can call to perform last_writer_win, but to handle it by the developer?

    Thank you so much for ur time.

    Tuesday, October 2, 2012 10:23 AM
  • if you include the last_change_datetime from the tracking table, you will have to make sure Sync Fx doenst try to treat it like all the other columns that you sync. when you modify the _selectchanges, you have to remember that everytime you provision. and you will have to modify the other stored proc that retrieves the destination row when a conflict occurs.

    adding a new column is the simpliest one.

    yes, you will have to implement your last writer win approach.

    Wednesday, October 3, 2012 1:58 AM
    Moderator
  • hi June,

    Thanks for the clarification!

    Wednesday, October 3, 2012 3:30 AM
  • hello JacelynC,

    did you implement your last writer win approach?

    Friday, October 19, 2012 4:54 PM
  • Hi Cangosta,

    Yes, I create an updatedTime column in my table, which will be updated with current time every time the row is updated.

    Saturday, October 20, 2012 4:13 PM