CRM-17464 remove deadlock inducing query
authoreileenmcnaugton <eileen@fuzion.co.nz>
Thu, 29 Oct 2015 08:26:04 +0000 (21:26 +1300)
committereileenmcnaugton <eileen@fuzion.co.nz>
Thu, 29 Oct 2015 08:42:45 +0000 (21:42 +1300)
CRM/Contact/BAO/Contact.php
CRM/Contact/BAO/Contact/Permission.php

index d3a3d443ae55d65f2bce80b48effc59a76da4ddb..c3996ad1bf8edf44a5955cfd95e3e1035436f038 100644 (file)
@@ -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.
    *
index 45a363b0f80f732f65e5284663dda2fab87a4476..dfb82a2aa7a0650c50755eab9f9875302e3fdbb9 100644 (file)
@@ -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;
   }