可排队的Apex-您尚未完成未完成的工作。请先提交或回滚,然后再调用

时间:2019-02-06 03:13:16

标签: salesforce apex

可排队的顶点有问题。如果您能为此提供帮助,那么很好吗?

他们的要求是将Salesforce对象同步到外部系统。

当前有一个触发器,该触发器执行可排队的顶点作业,并在最后进行标注和更新线索。

这在我们的测试过程中非常有效。另外,我们今天也进行了批量测试。但是,我们随机得到以下错误。

我将分享示例代码。

错误: 1:潜在客户编号:XXXXXXXXXXXXXXXXXX错误:System.CalloutException:您尚未提交未决的工作。请在调用outType之前提交或回滚:System.CalloutException 原因:null 消息:您有未提交的工作挂起。请先提交或回滚,然后再退出

我们仅在队列执行结束时进行更新。当我们测试单个或批量负载时,这非常理想。问题是断断续续的。

trigger TRIG_Lead on Lead (before insert, before update, after update, after insert) {
if (Trigger.isAfter) {
    if (Trigger.isInsert) {
        TRIG_Lead_Handler.afterInsert(Trigger.newMap);
    }
    if (Trigger.isUpdate) {
        TRIG_Lead_Handler.afterUpdate(Trigger.oldMap, Trigger.newMap);
    }
}

}

不共享类TRIG_Lead_Handler {

的公共
// A method that will be called by trigger in case of an after insert event
public static void afterInsert(Map<Id, Lead> newMap) {
    Map<Id, Lead> optimusLeads = new Map<Id, Lead>();
    System.debug('After insert trigger');

    // Looping through all leads
    for (Id leadId : newMap.keySet()) {
        Lead newLead = newMap.get(leadId);
        if (newLead.Optimus_Push_Criteria__c
                && newLead.Optimus_External_Id__c == null
                && newLead.Optimus_Push_Scheduled__c
                && !OptimusService.leadScheduledSet.contains(leadId)) {
            OptimusService.leadScheduledSet.add(leadId); // to prevent recursive pushes
            optimusLeads.put(leadId, newLead);
        }
    }

    if (!optimusLeads.isEmpty()) {
        System.enqueueJob(new QuableOptimusService('INSERT', optimusLeads.keySet()));
    }

}
public static void afterUpdate(Map<Id, Lead> oldMap, Map<Id, Lead> newMap) {
    Map<Id, Lead> convertedLeads = new Map<Id, Lead>();
    Map<Id, Lead> optimusLeads = new Map<Id, Lead>();
    // Looping through all leads
    for (Id leadId : newMap.keySet()) {
        // Declaring 2 variables: oldLead and newLead.
        // They represent the same lead before and after the update respectively
        Lead oldLead = oldMap.get(leadId);
        Lead newLead = newMap.get(leadId);

        if (newLead.isConverted) { 
            convertedLeads.put(leadId, newLead);
        }

        if (newLead.Optimus_Push_Criteria__c
                && newLead.Optimus_External_Id__c == null
                && newLead.Optimus_Push_Scheduled__c && !oldLead.Optimus_Push_Scheduled__c
                && !OptimusService.leadScheduledSet.contains(leadId)) {

            OptimusService.leadScheduledSet.add(leadId); // to prevent recursive pushes
            optimusLeads.put(leadId, newLead);
        }
    }

    if (!convertedLeads.isEmpty()) {
        reparentFeedItemsToConvertedOpportunity(convertedLeads);
    }

    if (!optimusLeads.isEmpty()) {
        System.enqueueJob(new QuableOptimusService('INSERT', optimusLeads.keySet()));
    }
}

}

具有共享类QuableOptimusService的

public实现Queueable,Database.AllowsCallouts {

String dmlType;
Lead currentProcessedLead;
Set<Id> IdSet;
List<Lead> leadList = new List<Lead>();
Set<Id> syncedIdSet = new Set<Id>();

/**
 * Constructor
 */
public QuableOptimusService( String dType, Set<Id> IdSet ) {
    this.dmlType = dType;
this.IdSet = IdSet;
}

public void execute(QueueableContext context) {

    // Query all the fields required for the service
    leadList = [ SELECT Id, Street, PostalCode, City, CreatedDate, Email, Status, Salutation, FirstName, LastName,
            Phone, BP_Number__c, MobilePhone, Deal_Comments__c, Degree_of_urgency__c, Housing__c, Language__c,
            Lead_Sources_EDF__c, Lead_Sources_Subtypes_EDF__c, Lead_Type__c, Net__c, Name_of_Sales_person__c,
            Number_of_Panels__c, Opt_out_communication_PV__c, Payback_Timeframe_in_years__c, Picture__c,
            Product_Interest__c, Region_in_Belgium__c, Total_earnings_over_time_horizon__c, Type_of_Web_lead__c,
            VAT_Number__c, Sales_Partner__c, Seller_ID__c, Shop_Location__c, Promocode__c, RecordTypeId,
            Company, Saving_in__c, Cell_Phone__c, Optimus_External_Id__c
    FROM Lead
    WHERE Id IN : IdSet AND Optimus_External_Id__c = null ];

    List<Lead> leadsToUpdate = new List<Lead>();
    OptimusService os = new OptimusService();

    try{

        Integer i = 0;
        for (Lead s : leadList) {
            currentProcessedLead = (Lead) s;

            if (dmlType != null && dmlType.equalsIgnoreCase('INSERT')) {
                currentProcessedLead.Optimus_External_Id__c = os.doLeadCreate(currentProcessedLead);

                if(currentProcessedLead.Optimus_External_Id__c != null){
                    leadsToUpdate.add(currentProcessedLead);
                }
            } else if (dmlType != null && dmlType.equalsIgnoreCase('UPDATE')) {
                os.doLeadUpdate(currentProcessedLead);
            }

            // Add Synced Lead Ids
            syncedIdSet.add(s.Id);
            if (++i == 80) {
                break;
            }
        }
        // remove synced lead Ids and enqueue again
        IdSet.removeAll(syncedIdSet);
        if (!IdSet.isEmpty()) {
            System.enqueueJob(new QuableOptimusService(dmlType, IdSet));
        }


        update leadsToUpdate;

    } Catch( Exception e) {
        System.debug('Error :' +e.getMessage());
    }

}

}

公共类OptimusService {

public String doLeadCreate(Lead l) {
    system.debug('*** LEAD CREATE');
    // login if needed
    if (Test.isRunningTest()) accessToken = 'abc';
    if (accessToken == null) {
        doLogin();
    }
    // headers
    Map<String, String> headers = New Map<String, String>{
        'cache-control' => 'no-cache',
        'content-type' => 'application/json',
        'fm-data-token' => accessToken
    };
    // body
    String body = generateLeadJSON(l);
    System.debug('--body--' +body);
    // request
    HttpRequest req = buildRequest(RECORD_URL + '/' + API_LAYOUT + '/', headers, body);
    System.debug('--req--' +req);
    // response
    HttpResponse res = sendRequest(req);
    if (res.getStatusCode() != 200) {
        throw new OptimusException('Received error from Optimus Lead Create Webservice: '
            + res.getStatusCode() + ': ' + res.getStatus());
    } else {
        LeadCreateResponse lcr = handleLeadCreateResponse(res.getBody());
        if (lcr != null && lcr.recordId != null) {
            return lcr.recordId;
        } else{
            throw new OptimusException('Lead create response null : '
                    + res.getStatusCode() + ': ' + res.getStatus());
        }
    }
}

public void doLeadUpdate(Lead l) {
    system.debug('*** LEAD UPDATE');
    // login if needed
    if (Test.isRunningTest()) accessToken = 'abc';
    if (accessToken == null) {
        doLogin();
    }

    // headers
    Map<String, String> headers = New Map<String, String>{
        'cache-control' => 'no-cache',
        'content-type' => 'application/json',
        'fm-data-token' => accessToken
    };
    // body
    String body = generateLeadJSON(l);
    System.debug('--body--' +body);
    // request
    HttpRequest req = buildRequest(RECORD_URL + '/' + API_LAYOUT + '/' + l.Optimus_External_Id__c, headers, body);
    System.debug('--req--' +req);
    // response
    HttpResponse res = sendRequest(req);
    if (res.getStatusCode() != 200) {
        throw new OptimusException('Received error from Optimus Lead Update Webservice: '
            + res.getStatusCode() + ': ' + res.getStatus());
    }
}


@TestVisible
private void doLogin() {
    system.debug('*** LOGIN');
    // headers
    Map<String, String> headers = New Map<String, String>{
        'cache-control' => 'no-cache',
        'content-type' => 'application/json'
    };
    // body
    String body = generateLoginJSON();
    // request
    HttpRequest req = buildRequest(AUTH_URL, headers, body);
    // response
    HttpResponse res = sendRequest(req);
    if (res.getStatusCode() == 200) {
        LoginResponse logres = handleLoginResponse(res.getBody());
        this.accessToken = logres.token;
    } else {
        throw new OptimusException('Received error from Optimus Login Webservice'
            + res.getStatusCode() + ': ' + res.getStatus());
    }
}


private HttpRequest buildRequest(String url, Map<String, String> headers, String body) {
    // Instantiate a new HTTP request
    HttpRequest req = new HttpRequest();

    // Set method and endpoint
    req.setEndpoint(url);
    req.setMethod('POST');
    req.setTimeout(120000);

    // Set headers
    if (headers != null) {
        for (String key : headers.keySet()) {
            req.setHeader(key, headers.get(key));
        }
    }

    // Set body
    if (body != null && body.length() > 0) {
        req.setBody(body);
    }

    system.debug('*** req: ' + req);
    system.debug('*** req.body: ' + req.getBody());
    return req;
}

private HttpResponse sendRequest(HttpRequest req) {
    // Send HTTP request and get HTTP response
    Http http = new Http();
    HttpResponse res = http.send(req);

    system.debug('*** res.status: ' + res.getStatus());
    system.debug('*** res.statuscode: ' + res.getStatusCode());
    system.debug('*** res.body: ' + res.getBody());

    return res;
}

}

谢谢。

1 个答案:

答案 0 :(得分:0)

此问题已在Salesforce Stackexchange here

上解决。

基本上,您必须在测试环境中限制入队