如何解决System.LimitException:具有电子邮件警报的工作流导致超出了Apex CPU时间限制?

时间:2019-06-29 22:26:27

标签: salesforce apex

我正在尝试对100条记录执行批处理测试方法,并获得CPU运行时限制错误。

我在代码中放置了Limits.getCpuTime()方法,并注意到没有工作流段的代码需要3148毫秒才能完成。但是,当我激活两个向每个用户发送电子邮件的工作流时,会收到CPU运行时限制错误。总的来说,没有这两个工作流程的过程大约需要10秒钟才能完成,而激活这两个流程大约需要20秒钟。

    @IsTest
static void returnIncClientAddress(){
    //Select Required Records
    User                                incidentClient      =   [SELECT Id FROM User WHERE Username = 'bbaggins@shire.qa.com' LIMIT 1];
    BMCServiceDesk__Category__c         category            =   [SELECT Id FROM BMCServiceDesk__Category__c WHERE Name = 'TestCategory'];
    BMCServiceDesk__BMC_BaseElement__c  service             =   [SELECT ID FROM BMCServiceDesk__BMC_BaseElement__c WHERE Name = 'TestService'];
    BMCServiceDesk__BMC_BaseElement__c  serviceOffering     =   [SELECT ID FROM BMCServiceDesk__BMC_BaseElement__c WHERE Name = 'TestServiceOffering'];

    //Create Incidents
    List<BMCServiceDesk__Incident__c> incidents = new List<BMCServiceDesk__Incident__c>();
    for(integer i = 0; i < 100; i++){
        BMCServiceDesk__Incident__c incident = new BMCServiceDesk__Incident__c(
            BMCServiceDesk__FKClient__c             =   incidentClient.ID,
            BMCServiceDesk__FKCategory__c           =   category.ID,
            BMCServiceDesk__FKServiceOffering__c    =   serviceOffering.ID,
            BMCServiceDesk__FKBusinessService__c    =   service.ID,
            BMCServiceDesk__FKStatus__c             =   awaiting_for_handling
        );
        incidents.add(incident);
    }
    test.startTest();
    insert incidents;
    test.stopTest();
}

我希望电子邮件工作流和警报可以批量处理并发送,而不会花费很多CPU时间,但是Salesforce似乎要花费大量时间检查工作流规则并在需要时执行它们。该过程的大部分时间似乎都花在了发送工作流的电子邮件上(由于这是一种测试方法,实际上并没有这样做)。

2 个答案:

答案 0 :(得分:0)

您无法控制工作流规则的执行时间。您可以尝试将它们转换为Apex并进行基准测试,以查看这是否可以减少所花费的时间,但是我怀疑真正的解决方案是您必须降低批量测试的速度。

事务的CPU限制为10秒。如果您的单元测试代码在没有工作流的情况下已经花费了大约10秒的时间(我不确定您3148 ms和10 s所指的范围是什么),那么您实际上只有两种选择:

  • 使在此对象插入时运行的自动化总和更快;
  • 减少您在此单元测试中处理的数据量。

尚不清楚您在此处实际测试的内容,但是如果它是Apex触发器,则应确保已正确对其进行了扩展,并且不消耗不必要的CPU时间(包括通过触发器递归)。查看日志中的调用堆栈(或简单地添加System.debug()语句)可能会有所帮助。

最后-确保在测试方法中编写断言。没有断言的测试方法几乎一文不值。

答案 1 :(得分:0)

在BMCServiceDesk__Incident__c或工作流程修改的对象上是否存在触发器?更新触发可能导致代码在同一执行上下文中多次执行,从而使您达到cpu限制。考虑将重入触发器中,或执行检查以仅在满足特定条件时才运行触发器。 否则,如果可能的话,请考虑重构代码,以便在同一循环内执行工作,因为循环(尤其是嵌套循环)会提高您的CPU使用率。通常,除非由于工作流程更新而执行触发器,否则工作流程本身不会提高CPU限制。