CRM-17464 remove deadlock inducing query
authoreileenmcnaugton <eileen@fuzion.co.nz>
Thu, 29 Oct 2015 08:26:04 +0000 (21:26 +1300)
committerJKingsnorth <john@johnkingsnorth.co.uk>
Thu, 25 Feb 2016 15:39:08 +0000 (15:39 +0000)
Signed-off-by: JKingsnorth <john@johnkingsnorth.co.uk>
CRM/Contact/BAO/Contact.php
CRM/Contact/BAO/Contact/Permission.php

index 51430c9bee36f51f45256d91ac4d90e2d9057f1a..0f8ba6291bda515e4981857749e3bc3707ec6d5c 100644 (file)
@@ -879,14 +879,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);
@@ -904,6 +897,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.
    *
index 2d42840291b910f0eb8758250b1138102bbd79f7..3a326ca6e34a3c4d130a3ce42373b40375a38c50 100644 (file)
@@ -141,7 +141,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;
   }