* @param array $contacts list of contact records to import
* @param int $maxErrors max number of contacts allowed to hit an error
* @param array $erroneousContacts a list of contacts that were skipped due to errors
* @return bool TRUE if the batch was committed
*/
function importBatchOfContacts($contacts, $maxErrors, &$erroneousContacts) {
$txMain = new CRM_Core_Transaction(TRUE);
$erroneousContacts = array();
foreach ($contacts as $contact) {
try {
$txNested = new CRM_Core_Transaction(TRUE); // NOTE: the "TRUE" makes for a nested transaction
if (!createContactFromProfile($contact)) {
$erroneousContacts[] = $contact;
}
} catch (Exception $e) {
$erroneousContacts[] = $contact;
$txNested->rollback();
}
$txNested = NULL; // finish the nested transaction
}
if (count($erroneousContacts) < $maxErrors) {
// batch was "good enough"; errors have been outputted to $erroneousContacts
return TRUE;
} else {
// too many errors; give up on the entire batch
$txMain->rollback();
$erroneousContacts = $contacts;
return FALSE;
}
}
</div>
</div>
<divclass="panelMacro">
!!! warning{width="16" height="16"} Marking a transaction for rollback is different from sending the ROLLBACK command to the SQL server – the two may not happen at the same time.The transaction is marked for rollback when an error is first detected, but the ROLLBACK command is sent when all outstanding copies of CRM_Core_Transaction finish-up.
For example, suppose the sequence of events include:
- Someone calls *registerNewContactForEvent*
- *registerNewContactForEvent* creates $tx (the first copy of *CRM_Core_Transaction*)