Add mechanisn for avoiding conflicts when deduping
We see occasional conflicts when 2 dedupe jobs try to dedupe 2 conflicts at the same time. It creates database deadlocks and noise on something where it feels like an Exception could be thrown and appropriately handled by the calling code. In addition it's possible for 2 jobs to 'successfully' dedupe the same contact at the same time. This looks like : Job 1 loads the contact, Job 2 loads the contact, Job 1 dedupes the contact, Job 2 dedupes the contact, based on data from before Job 1 deduped the contact. In some cases this means Job 2 makes incorrect changes because it is acting on out-of-date data.
Now that we are pretty happily using mysql locks in their post-5.7.5 incarnation of actually working I think we can use these to address the issue.
In general I don't think a dedupe task wants to proceed if any other process is changing the given contact. For that reason I think it makes sense for the dedupe task to try to acquire generic 'contact' locks on the 2 contacts it is trying to dedupe before loading data about them. If any other task has demonstrated that it is acting on them (by acquiring one of both contact locks) the dedupe task can throw an exception & the form layer or batch job layer can handle that (as they already do handle exceptions).
I propose the exception is a new Exception for the purpose - CRM_Core_Exception_ResourceConflictException