[SalesForce] How does Lightning Component Framework request boxcar’ing affect flows and transactions

If the lightning component framework batches together multiple update requests, are they all subject to the rules and limits of a single transaction?

From Queueing of Server Side Actions:

The framework queues up actions before sending them to the server. This mechanism is largely transparent to you when you’re writing code but it enables the framework to minimize network traffic by batching multiple actions into one request (XHR).

The batching of actions is also known as boxcar’ing, similar to a train that couples boxcars together.

The framework uses a stack to keep track of the actions to send to the server. When the browser finishes processing events and JavaScript on the client, the enqueued actions on the stack are sent to the server in a batch.

From Apex Transactions:

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.

We just encountered a situation that seems to suggest that the multiple updates will execute in one context with a single transaction's limits, but does not rollback all of them when a limit exception occurs.

We have a component that displays an Event and allows user to approve or remove. If the Event is removed, then a process-builder flow will delete all the child Participant objects for that Event.

Events are children of Courses, and we have another component to display a Course, which includes a list of the Event components. The Course component has a "Remove All" button that loops through the Event components and calls the Remove method. So each Event should have a separate update request, and the requests will probably be boxcar'd together.

However, when using this "Remove All" button on a Course that has several Events, we exceed the 100 SOQL query limit. Looking at the debug logs, there was a flow started for each individual Event. The first four of these flows were able to complete successfully before the limit was reached. Those first four Events come out of this with their decision updated to "Remove" and their Participants deleted. The rest of the Events are not updated, and still have their Participants.

So if they were all under the same transaction context, sharing the same limits, then why were some of them able to update? Shouldn't they all have been rolled back when the governor limit was reached?

Note: The limit exception doesn't normally happen when making this update. Modifying multiple Events through apex or a list view consumes the same number of queries as updating a single Event. In those cases the flow collects all the Events together and operates on the list.

Best Answer

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 behavior, I wrote the following code:

Apex

public class q192876 {
    @AuraEnabled public static void doAction() {
        for(Integer i = 0; i < 11; i++) {
            Contact[] a = [select id from contact limit 1];
        }
    }
}

Application

<aura:application controller="q192876">
    <aura:handler name="init" value="{!this}" action="{!c.init}" />
</aura:application>

Controller

({
    init: function(component, event, helper) {
        [1,2,3,4,5,6,7,8,9,10].forEach(function() {
            var action = component.get("c.doAction");
            // action.setBackground(true);
            $A.enqueueAction(action);
        });
    }
})

When the code is run as is, it produces a too-many-SOQL error. However, if you uncomment the line in the controller, it instead behaves correctly, producing ten logs instead of 1.

Note that using setBackground(true) means that you're implying that the transaction will take longer, so splitting the transactions will cause a minor delay compared to the boxcar effect.