System.TypeException:单个操作中不能超过10个块

问题描述 投票:0回答:4

我有这个非常奇怪的错误,“System.TypeException:在一次操作中不能超过10个块”,有没有人见过/遇到过这个?如果你知道如何解决这个问题,请指导我。

我试图在sObject列表中插入不同类型的sObjects。该列表永远不会超过10行。

salesforce apex-code apex
4个回答
2
投票

这篇帖子在这里:

https://developer.salesforce.com/forums/ForumsMain?id=906F000000090nUIAQ

表明它不是不同sObject的数量,而是超出导致此块限制的对象的顺序。换句话说,“1,1,1,2,2,2”有一个块,从“1”到“2”的转换。 “1,2,3,4,5,6”有六个块,即使元素数量相同。建议的解决方案是将对象放入按对象顺序排序的列表中。

您是否可以创建仅有2行或3行的合理测试用例?


1
投票

这个问题有两种可能的解释:

  1. 正如Jagular所说,你没有订购你试图插入的sobjects,因此列表中有超过10个“块”。
  2. 您尝试插入> 2000个记录,> 1个sobject类型。这个似乎是一个Salesforce Bug,因为错误消息与问题不匹配。

0
投票

场景1及其解决方案

如果您有混合列表,请确保没有任何顺序时对象不会分散。例如,A,B,A,B,A,B,A,B ....... Salesforce在将sObject类型切换10次以上时存在固有的麻烦。他们将此切换限制称为Chunking Limit。因此,在这个混合列表中,如果您对它进行排序然后将其传递给DML,那么Salesforce会更加快乐。例如。 A,A,A,A,B,B,B,B ......在这种情况下,salesforce只需要切换一次(即读取所有A对象 - >切换 - >读取所有B对象)。最大块限制为10.因此,这里我们是安全的。 listToUpdate.sort(); UPDATE listToUpdate;

场景2及其解决方案

我们必须要记住的另一点是,如果混合列表包含一个类型的更多对象,我们可以遇到TypeException。如截图所示,如果list包含1001个A类对象和1001个B类对象,则总对象数等于2002.允许的最大块数为10.因此,如果进行简单的数学运算,则对象数量为每个块都是2002/10 = 200. Salesforce还强制执行另一个调控器限制,每个块不应包含200个或超过200个对象。在这种情况下,我们必须预见有多少对象可以输入此代码,我们必须编写代码以便每次都为DML传递安全大小的列表。场景3及其解决方案

场景3及其解决方案

可能发生的第三种情况是,如果混合列表包含超过10种类型的对象,那么即使列表的大小非常小,当salesforce读取不同的sObject时也会发生切换。因此,我们必须确保在这种情况下,我们为每个sObject类型分配单独的列表,然后将其传递给DML。在顶点触发器或顶点类中执行此操作会导致一些麻烦,因为在上下文中启动了多个DML。在不同的上下文中为DML操作传递这种多个sObject列表将真正减轻您泵入平台的负担。考虑在批处理Apex作业中而不是顶点触发器或顶点类中执行此类逻辑。

希望这可以帮助。


0
投票

下面的代码应涵盖Arpit Sethi的所有3个场景。这是我从这个主题中获取的一段代码:https://developer.salesforce.com/forums/?id=906F000000090nUIAQ

并修改为涵盖场景2。

    private static void saveSobjectSet(List <Sobject> listToUpdate) {
    Integer SFDC_CHUNK_LIMIT = 10;

    // Developed this part due to System.TypeException: Cannot have more than 10 chunks in a single operation
    Map<String, List<Sobject>> sortedMapPerObjectType = new Map<String, List<Sobject>>();
    Map<String, Integer> numberOf200ChunkPerObject = new Map<String, Integer>();
    for (Sobject obj : listToUpdate) {
        String objTypeREAL = String.valueOf(obj.getSObjectType());

        if (! numberOf200ChunkPerObject.containsKey(objTypeREAL)){
            numberOf200ChunkPerObject.put(objTypeREAL, 1);
        }
        // Number of 200 chunk for a given Object
        Integer numnberOf200Record = numberOf200ChunkPerObject.get(objTypeREAL);
        // Object type + number of 200 records chunk
        String objTypeCURRENT = String.valueOf(obj.getSObjectType()) + String.valueOf(numnberOf200Record);
        // CurrentList
        List<sObject> currentList = sortedMapPerObjectType.get(objTypeCURRENT);

        if (currentList == null || currentList.size() > 199) {
           if(currentList != null && currentList.size() > 199){
                numberOf200ChunkPerObject.put(objTypeREAL, numnberOf200Record + 1);
                objTypeCURRENT = String.valueOf(obj.getSObjectType()) + String.valueOf(numnberOf200Record);            
            }
            sortedMapPerObjectType.put(objTypeCURRENT, new List<Sobject>());
        }
        sortedMapPerObjectType.get(objTypeCURRENT).add(obj);
    }
    while(sortedMapPerObjectType.size() > 0) {
        // Create a new list, which can contain a max of chunking limit, and sorted, so we don't get any errors 
        List<Sobject> safeListForChunking = new List<Sobject>();
        List<String> keyListSobjectType = new List<String>(sortedMapPerObjectType.keySet());
        for (Integer i = 0;i<SFDC_CHUNK_LIMIT && !sortedMapPerObjectType.isEmpty();i++) {
            List<Sobject> listSobjectOfOneType = sortedMapPerObjectType.remove(keyListSobjectType.remove(0)); 
            safeListForChunking.addAll(listSobjectOfOneType);
        }

        update safeListForChunking;
    }
}

希望它有所帮助,再见

© www.soinside.com 2019 - 2024. All rights reserved.