Can there only be one context user per transaction?

I am writing a class that grabs the context user before hitting a for loop that processes the new versions of the records. Or would it be better to grab the context user inside the loop?

public without sharing class emailOwner {

    public static void processChanges(List<sObject> newVersion, Map<Id,sObject> oldMap) {

        // Get context user
        User contextUser = userInfo.getUserId();

        for(sObject obj : newVersion) {
            Object oldobj = null;
            oldobj = oldMap.get(obj.id);
            //rest of code etc
            //Contextuser referenced etc

Outside of tests, yes every transaction has exactly one context user. For more information, have a read of Using the runAs Method:

Generally, all Apex code runs in system mode, where the permissions and record sharing of the current user are not taken into account. The system method runAs enables you to write test methods that change the user context to an existing user or a new user so that the user’s record sharing is enforced. The runAs method doesn’t enforce user permissions or field-level permissions, only record sharing.

You can use runAs only in test methods. The original system context is started again after all runAs test methods complete.

You can run code as another user, but it is hack-y and somewhat complicated, and creates a separate context anyway.

As for inside or outside the loop, it shouldn't make a huge difference either way, but there is some minor cost and you might as well cache it. Considering the negligible performance difference either way, it's mostly a matter of preference.

| improve this answer | |
  • The "cost" for getting it is a heap allocation of ~18 bytes plus a function call, which thanks to the new compiler is a sub-millisecond CPU cost. – sfdcfox Oct 14 '16 at 23:15
  • In more concrete terms, caching once compared to calling 10,000 times saves ~461ms, or about 0.0461ms per use. – sfdcfox Oct 14 '16 at 23:19
  • So pretty much negligible. It doesn't seem like the heap allocation would vary based on where you make the call, since exiting the function should release that particular allocation anyway. I guess 461ms is a bit more compelling than "might as well cache" though. – Adrian Larson Oct 14 '16 at 23:21
  • @sfdcfox any published info on the new compiler out there? – Eric Oct 15 '16 at 4:55
  • @Eric No, salesforce doesn't tell us more than they're willing to share, which is minimal. I don't even know how many versions there have been. What we do know is that the first version was basically an Abstract Syntax Tree that the Apex Code runtime executed, and it was slow, and later they've been marshaling calls back to native Java, which offered an improvement in speed (so, at least two major versions I'm aware of). The next major version is supposed to compile directly in to Java, which will be even faster than today's system (unless Winter '17 was that release...). – sfdcfox Oct 15 '16 at 6:31

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.