Situations when client should synchronize local card store with the server:
- Client app was off-line while user made some changes (for example, user updated some p-cards while traveling by plane), so client has list of changes (array of CommandTO) which need to be sent to the server.
- Client app polls the server and sees that client RootRevision number is less then the server's RootRevision, as a consequence the client app should pull changes from server. This could happen, for example if the user was using another client app on another device(laptop/iphone/etc) ).
- Every time the server processes a command (e.g. to create/edit/deleete a card or to add/delete card history, etc.), it increments a master RootRevision number for that user.
- Every resource identifier (object handle),e.g. BaseTO.id must be unique over time. No new resource should ever have the same BaseTo.id of any previous resource that has ever existed for this user.
- Client app should compare its local RootRevision with server RootRevision by periodically polling the server. If they're not equals, i.e. client RootRevision may less than server, that client should load changes from server CardSync_Synchronization#From server to client.
- Only after loading changes from server, and If client app has list of local changes, client should upload them to server CardSync_Synchronization#From client to server.
Command transfer object. Encapsulate commands in transfer objects. Please, see "Command" design pattern.
- String id - Represents command id, Client should use it it for processing command executed status @see CmdExecStatusTO.
- String name - Represents operation/command name. It must be one "Persist" or "Delete".
- String resourceType - Represents resource type. It might be "PCard","MCard","CardHistory","UserProfile" etc.
- String resourceId - Represents server resource identifier. @see BaseTO#id
- BaseTO resource - Represents resource.
Represents command executed status TO.
- String commandId - Represents command id. @see CommandTO#id
- String statusCode - Represent status code of executed command on server. It may be '0' or error code.
- String statusMessage - Represent status message of executed command on server. it may be used for returning error message.
From server to client
Client has to load changes from server passing client "RootRevision" by using:
- REST - GET /CommandLog request;
- JAX-WS - getCommandLog request.
These methods return array of CommandTO, which client must process.
From client to server
Client has to upload local changes to server by using:
- Rest - PUT /CommandLog request;
- JAX-WS - execCommands request.
These methods return array of CmdExecStatusTO. Client have to check CmdExecStatusTO.statusCode. if CmdExecStatusTO.statusCode is not "0" (server couldn't apply changes), client should update resource from server and reject local changes or ask user about.
Client passes list of command to server, however server executes each command in separate transaction. Server doesn't use transaction manager, in other world each component manage local transaction itself. So if one client app uploads changes to server and the other client app update something on server in the same time, some changes may be lost between clients.
For example, if user start client app on laptop (this client start synchronization (uploading changes to server)), and start working with iphone client (this client changes data), that some changes may not be synchronized between clients.
For avoiding it, client app should check the following conditions:
- if after uploading changes "new server RootRevision" not equals "old server RootRevision" plus number of correct executed command, client should load changes between "old server RootRevision" and "new server RootRevision" again;
- if after invoking server method server RootRevision was increased more than 1, client should load changes between "old server RootRevision" and "new server RootRevision".
However, the best way is re-implemented server for supporting high level transaction with JTA.