11

What is the best way to rollback some changes to the database inside an Apex method?

For example, in an Apex method, I insert multiple records (Opportunity / Quote / QuoteLineItems). When I execute my method, I want every DML operation to be executed without any errors. If any error is detected, I want the changes to be rollback (if the error happen between Quote and QuoteLineItem insertion, I want to remove the Opportunity AND Quote).

Is Savepoint sp = Database.setSavepoint(); the best alternative, or is there something I'm missing?

Thanks!

  • You say "SOQL executed without a problem", do you mean updates or creation of records? If so the proper term for that is "DML". – ca_peterson Mar 8 '13 at 23:50
  • @ca_peterson is correct. This is a DML question. It can be confusing considering SQL does selects and insert/update, but in Salesforce terminology the correct term is DML. That is the reason why this questioned was retagged as DML and had the SOQL tag removed. This isn't related to SOQL at all. – Jesse Altman Mar 8 '13 at 23:52
18

A Savepoint is exactly what you want. This is all apart of Transactions in Salesforce. You will want something like:

Savepoint sp = Database.setSavepoint();
try{
    // DML statements here
    insert opps;
    insert quotes;
    insert quoteItems;
}catch(Exception e){
    // An exception was caught. We need to revert back to our Savepoint
    // This will rollback all successful changes. So, if opps saved successfully
    // and then quotes failed, the opps will be rolled back as well
    Database.rollback(sp);

    // Add the error to the page for the user to see
    ApexPages.addMessages(e);
}
2

The one thing I don't get/like about Savepoints is how to amend a failure, and then re-submit the fix in the same transaction - so in the example below, the Account gets rolled back, but still has an Id assigned to it, so a subsequent insert fails because an Id is specified in the insert, but an update fails because it is not actually in the database. Maybe it'st just my lack of understanding of Savepoints on the Salesforce platform, but in case that's a requirement for you, wanted to offer a quick heads up...

Account a = new Account (Name = 'Test03082013');
Savepoint sp = Database.setSavepoint();
try{
insert a;
Contact c = new Contact (AccountId = a.Id);
insert c;
}
catch(Exception e){
Database.rollback(sp);
}
a.Name = 'Test2';
//insert a or update a both fail

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.