This data synchronization pattern is recommended for mobile apps where it is not likely for multiple end-users to change the same data while the apps are offline, as follows:
- The server database holds the master data that can change over time;
- The local storage database holds a subset of the master data and can be modified;
- Synchronization sends the modified data from the local storage to the server database and vice-versa;
- In the server, data is updated in a “last write wins” strategy. With this strategy, the latest data update overrides earlier updates.
The following is an overview of the Read/Write Data Last Write Wins pattern:
- Sends local storage data modified by the app back to the server;
- Updates database data with the one sent from local storage;
- Sends updated database data;
- Deletes and recreates data in the local storage with the data received from the server.
Download the sample module for the Read/Write Data Last Write Wins pattern, that uses companies as an example of data to synchronize. The following sections explain how to automatically generate this synchronization pattern and provide detailed descriptions of the data model and logic used in the sample module.
Automatically Generate the Pattern for an Entity
To automatically generate the logic needed to implement this pattern for an entity:
- In Service Studio, open the Data tab;
- Under Local Storage, select the local entity of the entity you want to synchronize with the server;
Right-click on the local entity and choose the Create Action to Sync Data (Read/Write) option.This option is only available if the local entity is linked to the database entity (with the Id as a foreign key to the database entity). That happens if you create local entities with a right click on Local Storage and choose Add Entity from Database...
This creates the actions needed to implement the Read/Write synchronization pattern:
- SyncLocal<Entity>: client action that starts the synchronization between the local entity and the entity in the server database. It sends the added, changed and deleted local records to the Sync<Entity> server action that handles the synchronization of the entity on the server side;
- Sync<Entity>: server action called by the SyncLocal<Entity> action, that synchronizes the received local entity records with the server database records. It returns the current records of the entity in the database to be updated in the client local storage.
Along with these actions, new attributes IsFromServer, IsModified and IsActive are added to the local entity to track changes and store meta-information needed by the synchronization process. To keep these new attributes updated and coherent for the synchronization process, the accelerator creates new client actions that must replace the use of the default local entity actions of the local entity:
- CreateOrUpdateLocal<entity>ForSync: replaces the CreateOrUpdateLocal<Entity> client action;
- DeleteLocal<entity>ForSync: replaces the DeleteLocal<Entity> client action;
- UpdateLocal<entity>ForSync: replaces the UpdateLocal<Entity> client action.
These client actions are created in the Logic tab, Client Actions, SyncActions_Local<Entity>.
To guarantee the success of the synchronization process when using this accelerator, you must replace the use of all entity actions of the local entity by the corresponding new actions created by the accelerator.
This sample defines a database entity
Company and its local storage counterpart
LocalCompany. Additionally, the
LocalCompany entity defines three metadata attributes to keep track of the synchronization status of the records.
The application logic must update the metadata attributes
IsActive of the local entity according to the following:
IsFromServer: if True, the record exists on the server;
IsModified: if True, the record has been modified locally;
IsActive: if False, the record was deleted locally but may not yet have been removed from the server.
The following is a description of the logic of the
OfflineDataSync client action:
Obtains the list of locally added Company records. The aggregate uses the following filter:
LocalCompany.IsFromServer = False and LocalCompany.IsActive = True
Obtains the list of locally updated Company records. The aggregate uses the following filter:
LocalCompany.IsModified = True and LocalCompany.IsFromServer = True and LocalCompany.IsActive = True
Obtains the list of locally deleted (inactive) Company records. The aggregate uses the following filter:
LocalCompany.IsActive = False and LocalCompany.IsFromServer = True
- Calls the
ServerDataSyncserver action with the lists of locally added, updated, and deleted Company records as inputs. The server updates the data in the database and returns the list of updated Company records;
- Deletes all Company records in the local storage;
- Recreates the Company records in the local storage using the list of records returned by the server.
The following is a description of the logic of the
ServerDataSync server action:
- Iterates the list of locally added Company records and creates the new records in the database. To avoid collisions, the
Company.Idis set to
NullIdentifier()so that the records are created with new identifiers;
- Iterates the list of locally modified Company records and updates the records in the database;
- Iterates the list of locally deleted (inactive) Company records and deletes the records in the database;
- Retrieves all the Company records from the database;
Assigns the list of Company records to the output parameter of the action, while setting appropriate values for the synchronization metadata attributes:
IsFromServer = True IsModified = False IsActive = True