Keeping data synchronized between various mobile devices can become quite a chore – newcomers usually fail at getting a working solution up, and books on the topic tend to be extremely thick.
We don’t have a wireless sync situation but incremental updates is
something that we have done in various systems that interact with
each other plus I’ve seen some good ideas on this elsewhere.
First, Apple has a notification service for the iPhone. The idea is
that the client does not bother the server until the server sends
it a
change notice. And the client does not notice the change notice until
a user decides they should run the application. This means that there
is only one iPhone app that is always polling the master update
thingy
that all services share and when it gets a change notice, it sets a
value (in their case it alters the icon on the GUI so that the human
sees there is an update). When the app gets launched by the human, it
sees the altered icon and goes and fetches it’s data from it’s server
and clears the icon alteration (or something like that). Thus, the
app
only does updates when the user triggers it to run.
This is a good system in that instead of every app trying to run it’s
own background process to keep itself up to date, only one app does
this and between updates it sleeps. So the processor usage and
network
traffic is small no matter how many apps want to keep themselves
updated.
Moral of the story, it would be good if you could use some built in
receiver (SMS maybe?). If not SMS, perhaps sync when the app first
launches and then ask the user how frequently they want the app to
wake the device and attempt a sync (reminding them that this will
affect battery life). You could have something like a sync every
minute for the next hour button. Try not to build code that always is
pinging the server. That would use up the battery especially when
most
syncs will probably have no changes to deal with.
Second, on the server side, every row in the database should
contain a
lastModifiedDate value that gets set each time the row is changed. We
use database triggers to keep that value updated. Then your sync
routine is very easy. Something like:
select * from thetable where lastModifiedDate >=
theMostRecentLastModifiedDateStoredLocally
And if in the first sync you are grabbing way too much data for a
single select (assuming you have a bunch of data) do it in manageable
increments.
set rowcount 100
select * from thetable where lastModifiedDate >=
theMostRecentLastModifiedDateStoredLocally
order by lastModifiedDate ascending
set rowcount 0
So that it gives you the oldest stuff in small chunks until you eat
up
all the changes.
Note, always have unique row IDs and always use the data you get to
replace existing rows. This allows the server to send you overlap
data
(data you got at the tail end of the last query) to make sure you
don’t miss anything.
Also note, theMostRecentLastModifiedDateStoredLocally is a date time
value but DO NOT use your local time on the device. Treat
theMostRecentLastModifiedDateStoredLocally as some incrementing value
and not as a date time. It looks like a date and time that you could
derive from your local clock, it is not. This prevents you from
getting messed up when daylight savings time changes or when the time
zone changes. We tend to keep this value as a separate data value
that
gets updated with each update pull from the server (so that we don’t
have to scan the local data to get the most recent value).
Third, if the data changes are non-stop such that even as fast as you
can grab them, new changes are getting put into the database, and you
really don’t need to have it continually get updates every second as
they occur, you can do something like, if the number of rows returned
is less than some number (lets say 5) then consider yourself done and
wait until your next update time period before grabbing more rows.
Fourth, you can lessen the load on the database by putting a proxy
service between the client doing the above SQL and the database. For
example, in the rowcount example you could have the client send
something like
getChanges(thetable,theMostRecentLastModifiedDateStoredLocally)
and the server could cache sets of data, perhaps 10 minutes worth of
changes, in a set of cache files with file names like
YYYYMMDDHHMM.txt
and it could just feed you back the files that are in the proper date
range (oldest gets sent first) and then for the last set of data, get
that from the database.
Finally, the goal is to find ways to minimize the communication
between the client and the server and to have the user be satisfied
with the update frequency.