Like most multi-user systems, Salesforce does not block users from viewing a record via the UI while an update is in progress. This can cause an issue where two users are updating the same record at the same time. I don’t mean “Click Save” at the same time, I am referring to an “update interval”, something like the following sequence of events:
Salesforce will reject the second update and display a message like so:
So how exactly does this work? When we click the Edit button while looking at a record, Salesforce documents the record’s “Last Modify Date” at the time of the click. When we click Save, Salesforce checks the date again. If it matches, Salesforce knows no changes occurred since we grabbed the record and allows the save to go through. If it differs, Salesforce knows someone else changed the record while we were editing it and displays an error. (This pattern is generally referred to as optimistic locking.)
This is a great solution when we have a user sitting in front of a computer screen who can see the error message and deal with it, but what about when two systems are trying to do a similar process? This is the classic case of an “update conflict”.
Clients often ask for a bidirectional data synchronization (integration) between two systems (and in my line of work one of those systems is always Salesforce). Every time, without fail, my immediate reaction is “Are You sure you want to do that? What about update conflicts?” to which I get a blank stare, or a “What are the odds of that happening?”. The problem is they aren’t thinking in terms of batch job run times or whole records.
Consider the following: We have a bidirectional data synchronization between and ERP and Salesforce, it runs every 15 min, first it pushes data from Salesforce to the ERP, then from the ERP to Salesforce.
So, in this case we are unknowingly making a rule that if data is updated in both systems in the same 15-minute interval, we will simply throw away the ERP update, even if there is no conflict at the field level.
Now, yes, we can write code to track field level changes (in both systems), and we can move to a more real time sync process, but the -more we try to put together a solution, the more we see the need for increased code complexity and a manual “update conflict log review” process, there’s just no getting around it.
So, what is my recommendation? – Conflict avoidance. Simply put, seriously question whether a bidirectional data synchronization is really needed, and if possible, go with a Two-way unidirectional sync instead.
Generally, there are three basic types of synchronization:
Unidirectional syncs are a one-way synchronization during which data flows from a source system to a target system. The source system is referred to as the master system because it “owns” the data. The goal is to bring the target system up to date with the latest data from the source system. In general, you don’t allow updates to the target system on any field owned by the master system. I say “in general” because there are instances in which there is a requirement to allow users to override the data in the target system, not push back that data to the source, and not have it overwritten by the source data the next time the synchronization job runs.
Bidirectional synchronizations are used when you need to keep data in sync between two systems and allow for users to update the same piece of data in both systems. For example, let’s say we want to allow users to update a company’s shipping address in the ERP system and in Salesforce, and we want the update to be reflected in the other system regardless of in which system the update was made. In this case both systems are considered to be the source and the target. Again, I recommend that bidirectional syncs be avoided whenever possible because of the complexities of dealing with update conflicts. You may think that a general rule of “the last system updated wins” will work, but it’s usually not that simple (as shown above). We need to come up with some set of rules on how to manage the data when it’s updated in both systems simultaneously (i.e. during the update interval).
In lieu of a bidirectional sync, I recommend you make two new fields (or sets of fields) in Salesforce. Going back to our example, we would create two sets of fields: one for the ERP shipping address and one for the Salesforce shipping address, and then either have a trigger (or a workflow) that has rules to populate the native Salesforce shipping address fields or a formula that calculates it based on some set of conflict resolution rules. This practice essentially turns your bidirectional sync into a two-way unidirectional sync, eliminating the risk of data loss. (Because we always have both the ERP address and the Salesforce address – so a user can deal with the issue if needed. Yes, there is a conflict but there is no data loss).
A two-way unidirectional sync is when you sync the same object in both directions, but each system syncs only some fields or records where there is no overlap. This lack of overlap means there can’t be any data conflicts, so you can just sync system A to system B, then system B to system A with no risk of data loss. It really is just two unidirectional syncs. It’s important to understand that this is fundamentally different than a bidirectional sync. With bidirectional syncs, you must deal with data conflicts; with two-way unidirectional syncs, you don’t. The terminology is often confused. People say “bidirectional” when they mean “two-way unidirectional.” What’s important is always to ask for clarification. Ask specifically if there is the potential for data conflicts and, if so, be sure to put in rules to handle them.
Here are the two most common two-way unidirectional use cases (That I have seen):
Generally, when people ask for a “bidirectional” integration, a “two-way unidirectional” integration will probably meet the business needs. True Bi-directional syncs are difficult to get right and usually require some level of manual user intervention to deal with conflicts. So, I find its best two avoid Bi-directional syncs where possible, and we have discussed a few techniques to do that.
Once we remove the need for conflict resolution, data synchronization becomes a relatively straight forward build.
This article is adapted from my book “Developing Data Migrations and Integrations with Salesforce: Patterns and Best Practices” (Apress December 2018)
Enjoyed this article? Visit my blog at: http://SalesforceDataBlog.com or subscribe by Email or RSS. Follow me on LinkedIn and/or Twitter.
Director of Professional Services