当前位置:网站首页>Salesforce Future method in salesforce – @future

Salesforce Future method in salesforce – @future

2022-06-24 00:04:00 repick

future Method is used to run a process in a separate thread when system resources are available , We can future Method is used for any operation that we want to run asynchronously in its own thread .

1. Generally used for the following 2 Kinds of scenes :

·external Web services callout

·Trigger in DML After implementation , Again CallOut operation .

2. Method constitution

· Specify before the method @future label

· When necessary static Method and returns a value void

· Arguments must be basic data types or collections of basic data types

· Arguments cannot use standard Object Type or sObject type

· Arguments are generally used List record IDs To transfer data

Composition example :

global class SomeClass {
    @future
    public static void someFutureMethod(List<Id> recordIds) {
      List<Account> accounts = [Select Id, Name from Account Where Id IN :recordIds];
      // process account records to do awesome stuff
    }
}  

3. Be careful :

· Arguments cannot use standard Object Type or sObject Type of reason ,future Time to wait during method execution , In the process Object There is a possibility that the value in , Easy to cause bad effects .

·future Method does not guarantee execution order ,2 individual future Methods are easy to execute at the same time , If you update a piece of data at the same time , It is easy to lock the watch , happen error.

·future Method cannot call another method that is also future Methods

4. example :

There are two ways , One does not specify @future, Another specifies @future, And verify whether the results are correct .

public with sharing class ExampleFuture {
    public static void methodNoFuture(Set<Id> idsSet) {
        String sql = 'SELECT Id,Name FROM Opportunity where Id in :idsSet';
        List<Opportunity> opps = Database.query(sql);
        List<Opportunity> newOppList = new List<Opportunity>();
        for(Opportunity opp : opps) {
            opp.stageName = 'Closed Won';
            newOppList.add(opp);
        }
        update newOppList;
        System.debug('>>>>>>>>methodNoFuture::'+System.isQueueable());
    }

    @future
    public static void methodFuture(Set<Id> idsSet) {
        String sql = 'SELECT Id,Name FROM Opportunity where Id in :idsSet';
        List<Opportunity> opps = Database.query(sql);
        List<Opportunity> newOppList = new List<Opportunity>();
        for(Opportunity opp : opps) {
            opp.stageName = 'Closed Won';
            newOppList.add(opp);
        }
        update newOppList;
        System.debug('>>>>>>>>methodFuture::'+System.isQueueable());
    }
}

Below is the test class , The difference is to call future When the method is used , The place to call must be 【Test.startTest();】 and 【Test.stopTest();】 Between , Otherwise, the call will not succeed .

@isTest
public with sharing class ExampleFutureTest {
    static testMethod void FutureTest001() {
        List<Opportunity> oppList = new List<Opportunity>();
        for(integer i = 0; i<200; i++){
            Opportunity oppItem = new Opportunity(Name='methodNoFutureOpportunity'+ i,
                                StageName='Perception Analysis',
                                CloseDate = Date.Today(),
                                DeleteFlg__c = true);
            oppList.add(oppItem);
        }
        insert oppList;
        Map<Id, Opportunity> oppsMap = new Map<Id, Opportunity>(oppList);
        ExampleFuture.methodNoFuture(oppsMap.keySet());

        List<Opportunity> oppUpdateList = [SELECT Id,StageName FROM Opportunity WHERE DeleteFlg__c = true];
        System.assertEquals(200, oppUpdateList.size());
        if (oppUpdateList != null && oppUpdateList.size() >0) {
            for (Opportunity oppUpdate : oppUpdateList) {
                System.assertEquals('Closed Won', oppUpdate.StageName);
            }
        }
    }
    static testMethod void FutureTest002() {
        List<Opportunity> oppList = new List<Opportunity>();
        for(integer i = 0; i<200; i++){
            Opportunity oppItem = new Opportunity(Name='methodFutureOpportunity'+ i,
                                StageName='Perception Analysis',
                                CloseDate = Date.Today(),
                                DeleteFlg__c = true);
            oppList.add(oppItem);
        }
        insert oppList;
        Map<Id, Opportunity> oppsMap = new Map<Id, Opportunity>(oppList);

        Test.startTest();
        ExampleFuture.methodFuture(oppsMap.keySet());
        Test.stopTest();

        List<Opportunity> oppUpdateList = [SELECT Id,StageName FROM Opportunity WHERE DeleteFlg__c = true];
        System.assertEquals(200, oppUpdateList.size());
        if (oppUpdateList != null && oppUpdateList.size() >0) {
            for (Opportunity oppUpdate : oppUpdateList) {
                System.assertEquals('Closed Won', oppUpdate.StageName);
            }
        }
    }
}

Execution results :

sObjects That Cannot Be Used Together in DML Operations

some sObject Upper DML The operation cannot be the same as other operations in the same transaction sObject Upper DML Mixed execution , For example, when inserting Account Table data , It is necessary to insert at the same time Role Of User, Now insert user Method needs to be specified @future

public with sharing class ExampleMixedDMLFuture {
    public static void useFutureMethod() {
        // First DML operation
        Account a = new Account(Name='Acme');
        insert a;
        System.debug('>>>>>>>>useFutureMethod11::'+System.isQueueable());
        // This next operation (insert a user with a role)
        // can't be mixed with the previous insert unless
        // it is within a future method.
        // Call future method to insert a user with a role.
        ExampleInsertUserFuture.insertUserWithRole(
            '[email protected]', 'xiang',
            '[email protected]', 'yu');
        System.debug('>>>>>>>>useFutureMethod22::'+System.isQueueable());
    }
}
public with sharing class ExampleInsertUserFuture {
    @future
    public static void insertUserWithRole(String uname, String al, String em, String lname) {
        System.debug('>>>>>>>>insertUserWithRole111::'+System.isQueueable());
        Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
        UserRole r = [SELECT Id FROM UserRole WHERE Name='COO'];
        // Create new user with a non-null user role ID
        User u = new User(alias = al, email=em,
            emailencodingkey='UTF-8', lastname=lname,
            languagelocalekey='en_US',
            localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
            timezonesidkey='America/Los_Angeles',
            username=uname);
        insert u;
        System.debug('>>>>>>>>insertUserWithRole222::'+System.isQueueable());
    }
}

Test class :

@isTest
public with sharing class ExampleMixedDMLFutureTest {
    @isTest static void test1() {
        User thisUser = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()];
       // System.runAs() allows mixed DML operations in test context
        System.runAs(thisUser) {
            // startTest/stopTest block to run future method synchronously
            Test.startTest();
            ExampleMixedDMLFuture.useFutureMethod();
            Test.stopTest();
        }
        // The future method will run after Test.stopTest();

        // Verify account is inserted
        Account[] accts = [SELECT Id from Account WHERE Name='Acme'];
        System.assertEquals(1, accts.size());
        // Verify user is inserted
        User[] users = [SELECT Id from User where username='[email protected]'];
        System.assertEquals(1, users.size());
    }
}

Execution results :

Execute... In the same transaction DML In operation , The following cannot be sObject And others sObject Use it together

  • FieldPermissions
  • Group
  • GroupMember
  • ObjectPermissions
  • PermissionSet
  • PermissionSetAssignment
  • QueueSObject
  • ObjectTerritory2AssignmentRule
  • ObjectTerritory2AssignmentRuleItem
  • RuleTerritory2Association
  • SetupEntityAccess
  • Territory2
  • Territory2Model
  • UserTerritory2Association
  • User
原网站

版权声明
本文为[repick]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/11/20211123230321092a.html