How does JA resolve data conflicts between JA Cloud and the offline device going again online

I read the article about Data Synchronization (Data Synchronization Priority - JourneyApps Docs), but I want some clarifications about what does ‘Data Download/Upload’ mean.

I have some scenarios that I can’t predict the result:

  1. The JA Cloud and device are synced. The device goes offline and the item was changed on the device with call to DB (change A). Then the external script updates that item (change B) in the JA Cloud (with JA Backend API). Then the device goes online.
    So, by Data Synchronization Logic the device should first upload changes from JA Cloud to device… and what will happen? will it overwrite device change or device change will overwrite JA Cloud change?

  2. The JA Cloud and device are synced. The device goes offline. The external script updates that item (change A) in the JA Cloud (with JA Backend API). Then the item was changed on the device with call to DB (change B). Then the device goes online.

  3. There are two synced devices. Both go offline. The first device changes the item (change A). The second device changes the item (change B). Then both go online.

Which change (A or B) will be in the result in the JA Cloud for those scenarios? Where is the part that solves conflicts of changing the same items (on the device during upload or during downloading change to JA Clouds)?

I would also be glad to have any general explanation on how such conflicts are resolved in JA.

Thanks!

Hi @khilda

This is an excellent question, and luckily the default behavior is relatively easy to understand.

In short, the default behavior for conflict resolution (which importantly is on a field level, not an object/row level) is that the last write to reach the Cloud wins, regardless of the when that change happened. Put in a different way, the last change to get “synched” to the Cloud will win.

So, in your scenarios, assuming everything is synched up at the end and all changes are on the same object and field, here are the answers of which changes will win:

  1. The JA Cloud and device are synced. The device goes offline and the item was changed on the device with call to DB (change A). Then the external script updates that item (change B) in the JA Cloud (with JA Backend API). Then the device goes online.
    - Change A will win (assuming Change A, the offline change, syncs to the Cloud after change B has already happened)
  2. The JA Cloud and device are synced. The device goes offline. The external script updates that item (change A) in the JA Cloud (with JA Backend API). Then the item was changed on the device with call to DB (change B). Then the device goes online.
    - Change B will win (again assuming Change B, the offline change, syncs to the cloud after change A has already happened)
  3. There are two synced devices. Both go offline. The first device changes the item (change A). The second device changes the item (change B). Then both go online.
    - The winner will be whichever change got synced after the other change. So if Change A reached the server first, then Change B will in. And if Change B reached the server first, then Change A will win

I hope that explains it.

If the default behavior is not adequate for a specific use case, then developers can implement their own custom conflict resolution strategy. We have seen manual (ie end user driven) and automatic (ie logic driven) custom conflict resolution strategies. These usually involve creating “temporary” changes / objects and then having the resolution strategy determine whether or not to ‘apply’ the change to the ‘master/official’ object. In this way you can have it so that the “latest” change is the one that always prevails, even if it was synced before an earlier one, or whatever else you may want to do

1 Like

@tielman, Thanks for the answer! The default behavior and scenarios are clear.
Did we talk about conflict with the sync of DB, right?

which importantly is on a field level, not an object/row level

Could you please explain in more detail what does this mean?
JA saves the whole objects, we can’t save only one field of the object. So, how exactly does it work?

developers can implement their own custom conflict resolution strategy. We have seen manual (ie end user driven) and automatic (ie logic driven) custom conflict resolution strategies.

Could you suggest or recommend any specific techniques for organizing custom conflict resolution?

I can only imagine the option that we will do a copy of the object from a regular DB to a LocalDB, where all changes will be saved. But it’s important for our app first to get synced device DB with JA Cloud (= gets all data/updates from the remote server), and only after that tried to solve conflicts.
But I don’t know how I could track the moment when the exchange ends and only then start sending local data…
I would appreciate for any ideas or recommendations!

Also, I’m confused with the Data Synchronization of the same item.
Because it says that ‘Application data Upload’ has priority 1, so let’s imagine that device has a spotty connection and only upload data from the JA Cloud with the new item changes. And there is also a change from the offline device.
What will be shown on the device - item from the JA Cloud or offline DB item?

When the device will go online again and reaches the moment of sending data (Application data Download), will the offline device change overwrite the JA Cloud change and then the final version, after all resolution conflicts, will get back to the device?

which importantly is on a field level, not an object/row level

Field level conflict resolution just means that if two “actors” are updating the same object but not the same field then there is no conflict to resolve. Not all systems work this way, some systems do a row/object level resolution, which means if two different actors work on the same object, then even if they are updating completely different fields the system will see this as a conflict to resolve.

developers can implement their own custom conflict resolution strategy. We have seen manual (ie end user driven) and automatic (ie logic driven) custom conflict resolution strategies.

In order to accomplish this most developers create a separate model which stores the temporary/pending changes. These temporary objects either store the entire state of the object at the time of the change or just the fields that were changed (and yes, having a copy of the object in LocalDB is a good way to figure out what has changed). They then use webhooks and a single threaded CC task to determine if those temporary changes should be applied to the master object. The logic that is used to determine if the changes need to be applied depends on the use case and desired outcome, but one example would be to compare the time of the temporary change vs the last time that object or field was updated and then basing the decision off of that.


Because it says that ‘Application data Upload’ has priority 1, so let’s imagine that device has a spotty connection and only upload data from the JA Cloud with the new item changes. And there is also a change from the offline device.
What will be shown on the device - item from the JA Cloud or offline DB item?

I think you misunderstood the order or definition of those priorities. The device will always upload first before downloading new data. Or said in a different way, the offline device changes will be synched, applied and taken into consideration before changed data is downloaded to the device.

Application Data Synchronization
Screen Shot 2021-07-26 at 10.43.41 AM
1 - Container uploads data changes from the device to the cloud (this will also apply these changes to the Cloud DB)
2 - Container receives App Logic updates
3 - Container downloads updated data from the Cloud to the device


When the device will go online again and reaches the moment of sending data (Application data Download), will the offline device change overwrite the JA Cloud change and then the final version, after all resolution conflicts, will get back to the device?

Yes.

(In most of our examples though the final version will already be on the device and will not be required to get downloaded again. For example if offline changes the name field from A → C, but online the name was changed from A → B, then once the offline change is synched it would change the name from B → C, and since the name on the device is already C it does not need to download that data again. Obviously there may be other changes that it does need to sync, but if that was the only change then no need to sync)

I hope this helps

1 Like

@tielman Got it. Thanks a lot!
And you’re right, I messed up the upload and download meaning.

1 Like