【问题标题】:System.TypeException: Cannot have more than 10 chunks in a single operationSystem.TypeException:在单个操作中不能有超过 10 个块
【发布时间】:2014-03-05 10:15:39
【问题描述】:

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

我正在尝试将不同类型的 sObject 一起插入到 sObject 列表中。该列表永远不会超过 10 行。

【问题讨论】:

    标签: salesforce apex-code apex


    【解决方案1】:

    这篇文章在这里:

    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 行的合理测试用例?

    【讨论】:

      【解决方案2】:

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

      1. 正如 Jagular 所指出的,您没有对尝试插入的对象进行排序,因此列表中有超过 10 个“块”。
      2. 您尝试插入 > 2000 条记录和 > 1 个 sobject 类型。这似乎是一个 Salesforce 错误,因为错误消息与问题不匹配。

      【讨论】:

      • 我知道条件 2 是我的情况。哎!!
      【解决方案3】:

      场景1及其解决方案

      当您有一个混合列表时,请确保对象没有散乱无序。例如,A,B,A,B,A,B,A,B...。 Salesforce 在切换 sObject 类型超过 10 次时存在固有问题。他们将这种切换限制称为分块限制。因此,在这个混合列表中,如果您对它进行排序,然后将其传递给 DML,Salesforce 会更开心。例如。 A,A,A,A,B,B,B,B... 在这种情况下,salesforce 只需切换一次(即读取所有 A 对象 -> 切换 -> 读取所有 B 对象)。最大块限制是 10。所以,我们在这里是安全的。 listToUpdate.sort(); UPDATE listToUpdate;

      场景2及其解决方案

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

      场景3及其解决方案

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

      希望这会有所帮助。

      【讨论】:

        【解决方案4】:

        下面的代码应该涵盖 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;
            }
        }
        

        希望对你有帮助, 再见

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-03-13
          • 1970-01-01
          • 2019-01-06
          • 1970-01-01
          • 2016-09-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多