0

I have created a very simple scenario where I'm creating a savepoint and trying to rolling back in future method. The behaviour is little confusing - I tried searching it over the net but I didn't find any post helping me: What I observed:

  • Account record created in the first transaction wasn't deleted when I tried Database.rollback method was executed in Future method - But the rollback did happen. I could see the Limits.getDmlStatements() value increased

Shouldn't the rollback method execution undo the creation of account record?

Also, is there any way to successfully achieve this - Create a savepoint in one transaction and rollback EVERYTHING from another transaction which was started by this first transaction?

Following is the snippet:

Public Class SynchronousClass{
    Static SavePoint sp = Database.setSavePoint();
    Id recId;
    public void createAccount(){
        Try{
            System.debug('Created Save Point in Synchronous class --> DML Limits: '+Limits.getDmlStatements()); //Gives me 1
            Account acc = new Account(Name = 'testAccount12kjlk3');
            Insert acc;
            recId = acc.Id;
        }Catch(Exception e){
            System.debug(e);
        }

        futureMethod(recId);

        System.debug(recId);
        System.debug('Synchronous class End --> DML Limits: '+Limits.getDmlStatements()); //Gives me 2

    }

    @future
    Public static void futureMethod(Id recId){
        If(recId != null){
            System.debug('Future before rollback --> DML Limits: '+Limits.getDmlStatements()); //Gives me 1
            Database.rollBack(sp);
            System.debug('Future after rollback --> DML Limits: '+Limits.getDmlStatements()); //Gives me 2
        }Else System.debug('Record creation failure and Future DML Limits: '+Limits.getDmlStatements());
    } 
}
4

No, this won't work. Savepoints and rollbacks are scoped inside a single transaction. Once the transaction completes, work is committed to the database. While you can delete committed records from another transaction, you can't roll it back.

Here:

Static SavePoint sp = Database.setSavePoint();

// ...

@future
Public static void futureMethod(Id recId){
    If(recId != null){
        System.debug('Future before rollback --> DML Limits: '+Limits.getDmlStatements()); //Gives me 1
        Database.rollBack(sp);
        System.debug('Future after rollback --> DML Limits: '+Limits.getDmlStatements()); //Gives me 2
    }Else System.debug('Record creation failure and Future DML Limits: '+Limits.getDmlStatements());
} 

In point of fact sp represents a different Savepoint in your future method. Static variables also do not live across transactions (no variables do, unless you're using a Stateful batch class or a Queueable with instance variables). Your static variable's initializer is called once in the initial synchronous transaction, and then a second time in the future transaction. That's why Database.rollback() doesn't throw a NullPointerException. It's simply rolling back nothing at all. The setting of the savepoint is the one DML operation you start with.

Also, is there any way to successfully achieve this - Create a savepoint in one transaction and rollback EVERYTHING from another transaction which was started by this first transaction?

No, this is impossible. Since System.Savepoint isn't serializable, you can't actually pass it to any type of Asynchronous Apex in the first place.

1
  • Perfect!! Thanks David - This also cleared another doubt I had - Why future method was even showing one dml operation.
    – sfdcnewbie
    Mar 7 '20 at 18:44
2

Database.rollback works when everything is happening in a single transaction.

The future method initiates a different transaction and cannot be rollbacked. Here after synchronous method commits the records in the database then async future method will be initiated.

If you really want to make both of the operations in a single transaction then don't use future method.

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.