$txNested=newCRM_Core_Transaction(TRUE);// NOTE: the "TRUE" makes for a nested transaction
if(!createContactFromProfile($contact)){
$erroneousContacts[]=$contact;
}
}catch(Exception$e){
$erroneousContacts[]=$contact;
$txNested->rollback();
}
</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*)
- *registerForEvent* creates $tx (the second copy of *CRM_Core_Transaction*)
- *registerForEvent* encounters an error and **marks the transaction for rollback** (but the SQL ROLLBACK is **not** executed yet)
- *registerForEvent* terminates – and therefore $tx is destroyed (but the SQL ROLLBACK is **not** executed yet)
- *registerNewContactForEvent* terminates – and therefore $tx is destroyed, and **the SQL ROLLBACK is executed**
</div>
$txNested=NULL;// finish the nested transaction
}
if(count($erroneousContacts)<$maxErrors){
// batch was "good enough"; errors have been outputted to $erroneousContacts
returnTRUE;
}else{
// too many errors; give up on the entire batch
$txMain->rollback();
$erroneousContacts=$contacts;
returnFALSE;
}
}
```
!!! warning
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`)