From ae44c3b99889a0bd5492bece48eaf07143b18fc1 Mon Sep 17 00:00:00 2001 From: eileenmcnaugton Date: Thu, 29 Oct 2015 21:26:04 +1300 Subject: [PATCH] CRM-17464 remove deadlock inducing query --- CRM/Contact/BAO/Contact.php | 35 ++++++++++++++++++++------ CRM/Contact/BAO/Contact/Permission.php | 1 - 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/CRM/Contact/BAO/Contact.php b/CRM/Contact/BAO/Contact.php index d3a3d443ae..c3996ad1bf 100644 --- a/CRM/Contact/BAO/Contact.php +++ b/CRM/Contact/BAO/Contact.php @@ -882,14 +882,7 @@ WHERE civicrm_contact.id = " . CRM_Utils_Type::escape($id, 'Integer'); //delete the contact id from recently view CRM_Utils_Recent::delContact($id); - - // Update the group contact cache - if ($restore) { - CRM_Contact_BAO_GroupContactCache::remove(); - } - else { - CRM_Contact_BAO_GroupContactCache::removeContact($id); - } + self::updateContactCache($id, empty($restore)); // delete any dupe cache entry CRM_Core_BAO_PrevNextCache::deleteItem($id); @@ -907,6 +900,32 @@ WHERE civicrm_contact.id = " . CRM_Utils_Type::escape($id, 'Integer'); return TRUE; } + /** + * Action to update any caches relating to a recently update contact. + * + * I was going to call this from delete as well as from create to ensure the delete is being + * done whenever a contact is set to is_deleted=1 BUT I found create is already over-aggressive in + * that regard so adding it to delete seems to be enough to remove it from CRM_Contact_BAO_Contact_Permission + * where the call involved a subquery that was locking the table. + * + * @param int $contactID + * @param bool $isTrashed + */ + public static function updateContactCache($contactID, $isTrashed = FALSE) { + + if ($isTrashed) { + CRM_Contact_BAO_GroupContactCache::removeContact($contactID); + // This has been moved to here from CRM_Contact_BAO_Contact_Permission as that was causing + // a table-locking query. It still seems a bit inadequate as it assumes the acl users can't see deleted + // but this should not cause any change as long as contacts are not being trashed outside the + // main functions for that. + CRM_Core_DAO::executeQuery('DELETE FROM civicrm_acl_contact_cache WHERE contact_id = %1', array(1 => array($contactID, 'Integer'))); + } + else { + CRM_Contact_BAO_GroupContactCache::remove(); + } + } + /** * Delete the image of a contact. * diff --git a/CRM/Contact/BAO/Contact/Permission.php b/CRM/Contact/BAO/Contact/Permission.php index 45a363b0f8..dfb82a2aa7 100644 --- a/CRM/Contact/BAO/Contact/Permission.php +++ b/CRM/Contact/BAO/Contact/Permission.php @@ -137,7 +137,6 @@ ON DUPLICATE KEY UPDATE operation=VALUES(operation)" ); - CRM_Core_DAO::executeQuery('DELETE FROM civicrm_acl_contact_cache WHERE contact_id IN (SELECT id FROM civicrm_contact WHERE is_deleted = 1)'); $_processed[$userID] = 1; } -- 2.25.1