13

The reason to use Savepoints and Database rollbacks is when you are doing multiple operations in a single transaction, and want to "roll-back" the entire sequence of operations if there was an exception or problem later on in the process --- e.g., after prior DML operations had been successfully committed, or after a callout was processed, etc. Now, a ...


8

If an exception occurs, the transaction is automatically rolled back. However if you specify an explicit false when using a Database method such as Database.update(acctList, false) - then the allOrNone behaviour is overridden, and a partial commit is allowed to happen. The optional opt_allOrNone parameter specifies whether the operation allows partial ...


7

The savepoint specifies the point to roll back to. All DML that occurs between setting the savepoint and performing the rollback is included in the rollback. If you did an update someAccount; inside your try block, you'd see the effect of that DML operation be rolled back. But that doesn't include the trigger event that started the whole process. The DML ...


5

Yes, it will work for the delete DML operation. From the documentation Transaction Control: Only when all the Apex code has finished running and the Visualforce page has finished running, are the changes committed to the database. If the request does not complete successfully, all database changes are rolled back. With regards to the Savepoint ...


5

Every separate request made by a user is an isolated transaction. In general, no transaction can directly interfere with another transaction (so, for example, a SavePoint will not undo records in a separate transaction). Database.setsavePoint sets a save point in the current transaction, and Database.rollback undoes any changes that occurred from the time ...


5

I wouldn't necessarily call it the perfect solution, but here are some ideas I've used to make my code more maintainable. Separate your Visualforce action method from your save method that performs DML operations. You never want your user to see the white exception screen so you want to catch all exceptions in your action method. But these exceptions ...


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){ ...


4

The problem you face here is that each operation is a self-contained transaction. So you don't have the same options available to you. If you want to use transaction control, you need to use Apex so that all of your operations are, in fact, wrapped in one transaction. The documentation on the AJAX Toolkit is completely devoid of any reference to Savepoint.


3

Yes. Your understanding is correct. You need to send external system a request to rollback. Otherwise it will be out of sync.


3

You should handle exceptions in triggers. If you don't, then your trigger won't be bulk safe, meaning any failure in a batch of up to 200 records will kill the entire batch, which is usually undesirable. However, within a trigger, there is no need for explicit save points. Instead, handle the DML failures, and use addError on any records where the recursive ...


3

If anyone ends up in the same situation the way to solve this is: if(!Test.isRunningTest()) { create savepoint } be careful not to forget to use the same if(!Test.isRunningTest()) { restore savepoint } if you're restoring.


3

When it says any DML statement that occurs after the savepoint, does it mean within that transaction, or across all changes that might have happened? Only within the same transaction. Also, is the manual savepoint the same as the automatic rollback on exception? Generally speaking, yes. Everything that would be rolled back by exception is also rolled ...


3

This Savepoint absolutely does serve a purpose. Basically, you can boil the structure down to: Savepoint sp = Database.setSavepoint(); try { insert someRecords; delete someOtherRecords; update anotherRecord; } catch (Exception pokemon) { Database.rollback(sp); } So, imagine if something goes wrong on that third DML Operation (update ...


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 ...


2

How many times a rollback executes generally. Will it executes recursively? You can have up to 5 save points active at once per transaction. Rolling back the second save point in five, for example, will roll back to that save point, invalidating the third, fourth, and fifth in the process. Also is it the case that the Database.rollback and savepoints ...


2

A rollback executes once and sets the database to exactly the state it was in when at the Savepoint. As for your limits question, it is easy to verify for yourself with the following anonymous script: Savepoint initialState = Database.setSavepoint(); system.debug(Limits.getDmlStatements()); // yields 1 insert new Account(Name='Demo'); system.debug(Limits....


2

The answers above appear to contradict each other, so it's worth adding some clarification. The need for Database.setSavepoint() and rollback depends in part on whether you are using a try/catch block in your code. One way to prompt a SystemDmlException is to set a phone field to a value with more than 40 characters. If you use Execute Anonymous to run ...


2

If the database upsert results in an ID value being allocated and set on the SObject, that ID value remains in the Apex code even though the ID value has been discarded as part of the rollback process in the database. So the next time you upsert the data for that ID is "not available". So add this (a clone that does not preserve the ID) right after the ...


2

You are correct this is not currently possible AFIAK as each execution of the methods in the controller are separate transactions and as you noted the Transient keyword is required. You will have to write your own rollback if possible by storing the previous values in the controller as properties and updating them on failure in method 2.


2

No. Database.SavePoint is only valid during a single execution context. A Database.Savepoint does not persist across execution contexts. You cannot start a transaction and then return to your client webpage in order to get additional data to post to another record. I suggest that you collect all information for B and C and save at the same time instead ...


1

If you are using insert, you can just catch any exceptions and rollback: System.Savepoint sp = Database.setSavepoint(); try { createParentRecords(); createFirstChildren(); ... } catch(DMLException ex) { Database.rollback(sp); } If you are using Database.Insert, so it does not throw an exception on error, you will need to return the results ...


1

If you are trying to insert a new record (as opposed to simply updating an existing one), then the cardRequest.ID != NULL condition will never be satisfied because the record Id is null until after it is inserted, so stdController.save() won't run. Your error messages aren't showing up on the page because the message is lost when the page is refreshed. ...


1

This wont work for a few reasons Without putting your batch invocations in separate startTest/stopTest blocks, you have no guarantee they will finish one after the other (they are two independent asynchronous transactions) Savepoint works per transaction and you can't rollback changes across transaction. In other words, each batch execute invocation can ...


1

The documentation on Transaction Control clearly lays out that a Savepoint cannot be used across trigger invocations: References to savepoints cannot cross trigger invocations because each trigger invocation is a new trigger context. If you declare a savepoint as a static variable then try to use it across trigger contexts, you will receive a run-time ...


1

Create a validation rule for the additional fields that become required when the Stage changes which includes a test if( Stage = B) or (!= B), depending on how you set up the validation rules. When you try to save a record and the Stage = B, those rules should be activated. When you write your rules, you'll need to consider how to handle any Stages that ...


1

I think something like this might make it easier to debug where your problem lies. private void save() { // Note: Provide ACID behavior Savepoint toBeforeState = Database.setSavepoint(); string failedIn = ''; string error = ''; try { failedIn = 'Parent'; upsert record; failedIn = 'TypeA'; ...


1

That's rights, all commits on dmls in triggers happen at the end of the trigger. You may opt to use rollbacks in case you wish to handle exceptions. For detailed exp, refer: https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_order_of_execution.htm


Only top voted, non community-wiki answers of a minimum length are eligible