首页 > 解决方案 > 如何修复 System.LimitException:带有电子邮件警报的工作流导致超出 Apex CPU 时间限制?

问题描述

我正在尝试对 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 似乎需要花费大量时间来检查工作流规则并在需要时对其执行。流程的大部分时间似乎都花在了发送工作流的电子邮件上(实际上并没有这样做,因为它是一种测试方法)。

标签: salesforceapex

解决方案


您无法控制工作流规则的执行时间。您可以尝试将它们转换为 Apex 并进行基准测试,以查看这是否会缩短所消耗的时间,但我怀疑真正的解决方案是您将不得不减少批量测试。

事务的 CPU 限制为 10 秒。如果您的单元测试代码在没有工作流的情况下已经需要大约 10 秒才能完成(我不确定您的 3148 ms 和 10 s 到底指的是什么),那么您实际上只有两个选择:

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

目前尚不清楚您在此处实际测试的是什么,但如果它是 Apex 触发器,您应该确保它被适当地批量化并且不会消耗不必要的 CPU 时间,包括通过触发器递归。查看日志中的调用堆栈(或简单地添加System.debug()语句)可能会有所帮助。

最后 - 确保在测试方法中编写断言。没有断言的测试方法几乎毫无价值。


推荐阅读