22

Update, Summer '17: Platform Events are now GA. Note the following from the docs: Platform Events and Transactions Unlike custom objects, platform events aren’t processed within database transactions in the Force.com platform. As a result, publishing platform events can’t be rolled back. Note the following: The allOrNoneHeader API header is ...


14

I wrote a bit on my blog last week about how I was using the Tooling api to effectively create an "eval()" method. You could replace the transaction mechanism with a similar eval mechanism. The "eval'd" transaction code would still roll everything back, but the get message would be available for the eval exception to return. see http://codefriar.wordpress....


13

Invoking Database.rollback not only rolls back inserts, but it goes much, much further. It also rolls back: any DML operations, including insert, update, delete, undelete, convert lead, etc. sending of email: any calls to Messaging.sendEmail after the savepoint will be undone, meaning the email will be removed from the message queue of email to send (which ...


12

The lock is released end the transaction. The boundary you cross to do so may be a method exit, trigger completion, etc. It may be when you exit the static context entirely, but it will not be released simply by performing DML. The DML Statement is only a part of the transaction, and will not constitute a transaction boundary in itself. Here is how the Apex ...


10

Use batch Apex as described e.g. Force.com Batch Apex and Large Data Volumes. This allows work over a large number of SObjects (or other objects) to be executed in batches where each execute method has its own set of governor limits. Added after nvr's first comment: You can run a sequence of batch Apex jobs - a chain - by starting a new job in the finish ...


9

No, you can't force a commit. The specific reason why is because commits occur at the end of the entire transaction. The data is committed after the DML, but isolated from the rest of the database until after the page finishes (so it can roll back in the event of an exception). Shared View State If the page shares the same controller and extensions as the ...


8

You can't directly do this. While Java does have a syntax for this via anonymous classes, that isn't a language feature of Apex Code. The closest you can get would be to write an interface and implement that in a class, like this: public class Myclass { public interface rollbackable { void doSomething(); } public static void rollback(...


8

From what I can tell, it appears that the boxcar effect in Lightning has multiple transactions, but a single governor limit shared across all transactions. It's not in the documentation, which suggests that this might be a bug. For now, consider performing some of the actions as background processes, which inhibits the boxcar effect. To demonstrate this ...


8

See this answer where I experimented with the limits and came across some rather interesting answers: Question 1: will we hit 101 SOQL query limit in this case? Yes. For now, governor limits are aggregated across all actions that occur in the same transaction. Use setBackground to force your larger methods to be called in separate processes, or use a ...


6

I've been blasting away at this, trying to best apply some of the contributions, notably: JeremyNottingham with the exemplary Database.Stateful pattern, MLucci's technique to 'empty out' the successful list members, leaving the failures known, Phil Hawthorn and Kevin P who immunize the execute by busting out of it to do the work, However, I believe I have ...


6

Interesting question with some interesting answers. I think/hope I've understood what you're asking. In some respects, this feels a bit like fighting the platform here, and I guess it'll depend on how you feel about doing callouts back into the same instance of Salesforce using UserInfo.getSessionId(), but I think you could do something using this approach ...


6

The way we have resolved (or worked around) this in our package is basically by taking transaction control away from the platform. First we set a savepoint, then we do the processing, and if an exception occurs we manually rollback, and then we process the error (store it, send an email, ...). An example of this can be seen at work in the run method of ...


6

If you mark your variable as static it will persist between before and after triggers, but only if you leave the variable in a class (if you have a static variable in the actual trigger, it will not persist across invocations). So, your code would look like: public class OpportunityTriggerHandler { private static Set<Id> idsToRecompute; public void ...


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


4

No, each transaction will occur with exactly one user. Two simultaneous edits on two different records will result in two simultaneous transactions occurring in parallel.


4

My understanding is that a SQL READ UNCOMMITTED (or old school WITH (NOLOCK)) will allow you to query a value while another transaction has a lock on that record. This would correspond to where one Salesforce transaction has done a FOR UPDATE SOQL query on a record and hasn't completed the transaction yet (the entire request must complete successfully to ...


4

Yes, you can use rollback with updates, there's an example shown in the documentation on transaction control. Account a = new Account(Name = 'xxx'); insert a; System.assertEquals(null, [SELECT AccountNumber FROM Account WHERE Id = :a.Id]. AccountNumber); // Create a savepoint while AccountNumber is null Savepoint sp = Database....


4

I've come at this from the perspective of when the logging records. The first and last thing the Apex log records will be EXECUTION_STARTED and EXECUTION_FINISHED respectively. From Debug Log Details Execution Units An execution unit is equivalent to a transaction. It contains everything that occurred within the transaction. The execution is delimited ...


4

They are not the same. First scenario Error is thrown, but caught by the try catch. You are then adding the error to the page by using the ApexPages.addMessage() function. This is a better experience for the end user since the error will show at the top of the current page they are on. Second Scenario Error is encountered and user will be redirected ...


4

You can't explicitly commit a transaction. It is committed once the transaction ends successfully without an error. Note that each execute call in your batch is exactly one transaction. The results of a batch processing running from start to finish is 2 plus Records Processed divided by Batch Size, rounded up. Example: Process 500 records in a batch size of ...


4

One could argue that you don't need to test explicitly for uncaught system exceptions and subsequent system rollback because that is SFDC's job to verify this works, not yours. A rough analogy to this is you don't need to verify SFDC can send the email as long as you don't get an error/exception using Apex outbound email sendEmail(). Or, you don't need to ...


4

Follow the link to sObjects That Cannot Be Used Together in DML Operations to better understand (emphasis mine): DML operations on certain sObjects, sometimes referred to as setup objects, can’t be mixed with DML on other sObjects in the same transaction. This restriction exists because some sObjects affect the user’s access to records in the org. You ...


3

Any DML operations in the same transaction performed after Database.setSavePoint would be rolled back. This means that multiple users (and even the same user in multiple transactions) are isolated from each other, so the opportunity would be unaffected.


3

In our code, we currently rely on 2 custom objects to be inserted on the starting of the page. The reason for this problem was that some where our code was throwing a null pointer but Salesforce rolled back the entire transaction. Could you post the code you're using to do this? Unless you're also saving the page state when it loads, those objects won't be ...


3

Asynchronous by definition gives the notion of a queue so will be processes only when resources are available. I wonder if this is exactly why salesforce only let's you pass only native values as parameters rather than object instances. In this way it makes you query any data that you might be modifying rather than trying to update a previously cached ...


3

I just tested this, and it's available immediately in the same transaction, before the current transaction completes. Obviously, this Id won't be available to other transactions before "final commit," but by the time T2 runs, it is guaranteed to have access to that record. futureimm.exec(); asyncapexjob j = [select id from asyncapexjob order by createddate ...


3

Yes, two transactions can absolutely overlap. Let's say for instance that Object takes about two seconds to save. Until that transaction completes, the number of records in the database won't change. So if you get five hits per second over a certain time span, the first ten will have the same value. A couple of notes: There is a field type of Auto-Number ...


3

The collection itself remains the same, but the context records are modified. Consider the following contrived example: Service Layer public with sharing class MyObjectService { public static void setTextField1(List<MyObject__c> records) { for (MyObject__c record : records) { record.Field1__c = 'Hello'; } ...


3

What it's getting at here is that each Flow is not its own independent transaction. If it's an autolaunched Flow, it's executing as part of the transaction for whatever functionality launched it - so if you go from Process Builder, for example, into an autolaunched Flow, the two elements take place in the same transaction. Waiting Flow interviews are ...


3

First of all, you do not need to set SeeAllData=true if you want to see User records in a test. You always see them. Second of all, as outlined here the standard workaround to create a separate transaction inside your test method is to use system.runAs(user). system.runAs(new User(Id=UserInfo.getUserId()) { // separate transaction } In an actual test, ...


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