Using savepoint and rollback in apex salesforce

In this post i am going to demo how to use savepoint and rollback in apex. Before we start with how to use savepoint rollback, let us see why we need to use it in first place and also see what impact we may have to face if rollback is not used.

An important thing to understand while writing apex is how and when an apex dml transaction gets committed to database. An important practice that everyone follows is to write try and catch whenever we have dml transactions happening in our code. In case of try catch important things to note-
1. Code execution transfers to catch from the point where an exception has occurred
2. All the transactions that happened before the transaction that threw exception are actually committed to the database and this could be a problem where you want either all or nothing to happen.

This is applicable only in case of multiple dml transactions in one try block. In this case we can use savepoint &  rollback to make sure nothing is committed to the database in case exception occurs and making sure system is restored as it was at the starting point where savepoint is mentioned.

In case if your code does not use try catch blocks then no matter where exception occurs nothing will be committed to the database. That is, say if you have 3 transactions and the exception is thrown at 3rd dml then all the previous transaction will not be committed to database.

In the example below we will see all the points that we have discussed above. A visualforce page below has a controller that has three dml transactions happening one after another. An account record is inserted then a contact record and finally a lead record is created. In order to demo rollback, i have placed a validation rule on lead that will not allow lead record to get created and hence throw a dml exception and then we can see rollback demo.

So as to use savepoint and rollback we have to first specify the point at which you want the transaction to get rolled back and then use rollback statement to actually roll the operation back. For example.

Savepoint mysavepointt = Database.setSavepoint();
//your code here line 1
// your code here line n
//my code here line x

In this case transaction will be rolled back to savepoint just above line 1, and then again continue from line x just as if line 1 to line n were not executed at all or as if they were not present.

I have created 2 methods in controller, both the methods do the same thing except that one method uses rollback and the other does not use it. Both the methods have try catch blocks in place.

Visualforce Page Controller Class
In case of first method which does not use savepoint & rollback, you can see that first two dml transactions succeed thus inserting a new account and contact record but the third dml fails with a dml exception(as i had set a validation rule to stop the lead from getting created). As a result you can see that no. of newly created account and contact equals one where as lead count is zero. This happens dispite there was exception in apex transaction, that means partiall operations were committed to the database.

In the second method that uses rollback, you can see that none of the dmls are commited to the database and hence all the counts are zeroed and thus nothing is committed to the database as there was an exception thrown during lead creation and all the dml transactions are rolled back to the savepoint.

1 comment:

  1. Hello Gadekar,
    I am still not able to figure out one thing. As per salesforce statement which says "An Apex transaction represents a set of operations that are executed as a single unit. All DML operations in a transaction either complete successfully, or if an error occurs in one operation, the entire transaction is rolled back and no data is committed to the database. The boundary of a transaction can be a trigger, a class method, an anonymous block of code, a Visualforce page, or a custom Web service method."

    In this example, why do we need Savepoint because if transaction is not completed then it should be rolled back automatically