Conflicts
Overview
In general, the last Zync wins if more than one user is editing the same record. But with Field Level Merge, you can elect to only sync the fields that have changed, so a user editing one part of a record won't conflict with another user editing another part.
GoZync offers three ways to reduce conflicts:
Syncing just the data a user "owns" ie a found set. More here.
"Checking out records" so that records pulled down to mobile are locked on the server (below).
Using field level merge to only sync changed fields instead of changed records (below).
Conflicts are not an issue if you're syncing data specific to the mobile user and/or you architect your database correctly (have a table of notes records instead of a notes field, for example).
Details
Out of the box, we take the primary key of a record you sent up to the server and see if there is a match in the hosted table in your file: if there is, we're editing that record. If there is not, we're making a new record.
So if you send a lot of edits to the same record – or separate users send separate edits – we'll process those in the order received and last edit wins. And of course the same thing applies in Mobile: if a record with that primary key already exists on Mobile, GoZync will edit it when bringing down records from the host.
Note that you can modify this behavior with Custom Field Mapping so you can intervene, change the order in which we process edits, or branch the scripts to protect certain fields or records.
But with Field Level Merge you likely don't need to do this kind of thing...
For your first zync, turn field-level merge off.
Field-level merge can make first syncs slower than normal, so while you're testing, have it off unless you have a lot of container fields.
Then come back here and learn what field-level merge is all about, and when it can make your syncs faster.
What is field-level merge?
This is an optional setting on the Zync Options tab of GoZyncHosted (select a layout on the Dashboard, then click "Integration & Options" and you'll see a tab for Zync Options).
When this is turned on, GoZync will only send the fields that have been changed since the last Zync, instead of sending the whole record.
This can be a huge help if both the mobile user and hosted users are editing the same record. If you edit someone's phone number, and I edit their name, field-level merge lets both those edits get to the same record.
Or imagine that you have a collection of photos about a building on your iPad. Without field-level merge, editing the caption of one photo would cause all the photos on that record to be sent up to the server: with field-level we only send the caption.
We have some notes on this under the heading "speed", but field-level merge can also make your Zyncs much faster, as there is less data being sent. This is especially true with photos, if you're only editing some of the photos some of the time.
Field-level merge has its own overhead, so while it can really speed things up, it only does so in some cases and is less useful (and slower) on the Pull than on the Push. Read more on this here: speed.
Can I mark records as "checked out" records so only the mobile user can edit them?
Absolutely. In fact, this is one of the most useful workflows GoZync enables. Note that checkout is not supported in the free version of GoZync, but it is in the GoZync Demo.
What checkout looks like.
When users pull records down from your hosted solution, the record is marked as "checked out". You can simply set a field called "out" to 1, or record something more elaborate, perhaps including the name of the user who downloaded it and when they did so.
(Remember, users can download just their own records, so it's not like it would be a surprise who downloaded the record, but seeing the name can give you an extra sense of reassurance, and can remind staffers – who may not know all the business rules – who owns which records.)
You'd then enforce the checkout--and lock the record--by crafting access privileges in your hosted solution that prevent checked out records from being edited. This is great because users on the hosted solution (users "in the office") can edit records up until the moment a mobile user checks them out. Imagine: updating trouble ticket details up until the moment a mobile technician actually begins heading to the customer's location, but being prevented from changing it after that. Users in the office would then know they need to call the mobile technician to communicate any new details about the now checked out ticket.
Once the ticket is resolved and the mobile user syncs their updated ticket back to the hosted solution, the ticket is "checked back in" and is now editable again by users in the office.
Checkout in Action.
Watch this short video of checkout in action, along with a walkthrough of how we do it.
Todd Geist also demonstrates checkout as part of his "Three Favorite GoZync Features".
How to implement it.
Getting this working in your solution is pretty simple. Reading up on downloading found sets will help give you some context for the changes that follow. You'll also use Custom Field Mapping to implement this, so read up on that as well (custom field mapping is one of the most powerful features of GoZync).
Checking out. Create a "checked out" field in your hosted solution. Feel free to add this to layouts, but don't add it to the layout used for zyncing in GoZyncMobile.fmp12 as there won't be a matching field on the mobile side. Create a branch in the script "Custom Field Mapping: Transformation and Hooks" for your table-- you'll create a branch for both the push and the pull, that is for both "gzm_YourTable" and "gzh_YourTable".
In the "pull" branch--the one based on "gzh_YourTable"-- set your checked out field to a literal value like "1" like this:
SetField [ gzh_YourTable::checked_out ; 1 ]
In the "push" branch--the one based on "gzm_YourTable"-- you'd then clear your checked out field or set it to a literal value like "0" like this:
SetField [ gzh_YourTable::checked_out ; 0 ]
Not that in both the push and the pull it is the hosted record we're editing when it comes to checkout. This may be a little different than other SetField() steps you have going on that script where on the pull you're often setting fields in mobile records.
Last Zync Time If you're pulling records that are tagged as "scheduled" or "ready", for example, you want to sync based on that, regardless of last sync time. The script "Filter Records To Pull" has an option to disregard this per table, those lines are disabled by default: you'll likely want to re-enable them when doing checkout.
Your Filter Criteria. In our example file (WorxHosted) you'll see that we mark a record with a status of "Scheduled" when it's ready to go down to the iPad and with "Checked Out" when it's been pulled. Our filter criteria in the script "Filter Records To Pull", however, pulls records of both statuses. The reason is that if you only pull "Scheduled" items, GoZync will consider those as the only ones that should be on the iPad... and will delete the ones marked Checked Out from your device. So it's best to think of the find requests as the criteria for the records that should be on your iPad, not just the new ones you want to get to your iPad.
Preventing Edits of Checked Out Records. In your hosted solution, use FileMaker's built-in access privileges to prevent editing of records where "checked out" is not empty (or zero). In relational solutions you'll want to apply this restriction to child records as well: one should not be able to edit an invoice line item if the invoice is checked out, for example.
That's all. Pretty cool, isn't it?