You need to sign in to do that
Don't have an account?
Tony Williams 9
DML Limit 10000 Reached While Processing 9455 Account Team Objects
HI I am running a batch scirpt that has up to 9455 accounts. I need to update their acoucnt objects. The problem is that I have code that has to insert 3 Account Team Members per each Account record that is being iterated or 3 DML * 9455 = 28.365K. The Account Team Objects being updated don;t have any triggers that do any firing.
Q) How can I avoid this "DML Limit of 10000" issue?
Q) Should I increasemy batch limit? Currently this is what I am using: Database.executeBatch(job, 10);
Here is the code and Thanks.:
Q) How can I avoid this "DML Limit of 10000" issue?
Q) Should I increasemy batch limit? Currently this is what I am using: Database.executeBatch(job, 10);
Here is the code and Thanks.:
BATCH: =================================================================== global class BatchUpdateAccountTeams implements Database.Batchable<sObject>,Database.AllowsCallouts, Database.Stateful { global String query; global Integer accountSize = 0; List<Account> accountsToUpdate = new List<Account>(); global class UtilException extends Exception {} global database.querylocator start(Database.BatchableContext BC){ //*****************************************************************************************************************************************************************************p //Select All active US Accounts that have counties and states //NOTE: You don't need to get all Physical address components just the city and state. //***************************************************************************************************************************************************************************** if(query == null) { query = 'Select Id,Mailing_Address_Book__c,Physical_County__c,Physical_State__c ' + ' From Account WHERE Status__c = \'Added\' ' + ' And Physical_County__c <> null ' + ' And Physical_State__c <> null ' + ' And Registration_Level__c = \'R1\'' + ' And Type = \'Church\'' + ' And RecordType.Name like \'%US Organization%\' limit 10000'; } system.debug('<< QUERY >> '+query); return Database.getQueryLocator(query); } global void execute(Database.BatchableContext BC, List<sObject> scope){ List<Id> accountIDs = new List<Id>(); //List<RecordType> rec = [Select Id from RecordType where Name = 'US Organization' Limit 1]; //1. Get access to all Active US Organizations having Physical counties and states. for(sObject s : scope){ Account thisAccount = (Account)s; accountsToUpdate.add(thisAccount); accountIDs.add(thisAccount.Id); accountSize++; } //accountSize = accountsToUpdate.size(); system.debug('<< Max Accounts found>> '+accountSize); //2. Update The Account Teams for these accounts with the most recent account team personnel including VP of US Missionaries if(accountsToUpdate.size() > 0){ TeamMemberAccounts.handler(accountsToUpdate,accountIDs); TeamMemberAccounts.handler(accountsToUpdate); } } global void finish(Database.BatchableContext BC){ List<Messaging.SingleEmailMessage> emailList = new List<Messaging.SingleEmailMessage>(); Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); //Send email to all in Account Teams Updates Group if any account team member objects were created/updated if(accountSize > 0){ //3. Get User Ids for the Acocunt Team Updates Group. Map<Id,User> users = new Map<Id, User>([SELECT Id, Email FROM User WHERE Id IN ( SELECT UserOrGroupId FROM GroupMember WHERE Group.Name = 'Account Team Updates')]); List<String> userEmail = new List<String>(); //We need to make sure that the Test coverage will work when testing emails otherwise a REQUIRED_FIELD_MISSING, Missing exception will occur. if(Test.isRunningTest()){ User tUser=[Select Email from User where Name Like 'MyAwana%' Limit 1]; userEmail.add(tUser.Email); }else{ for(User someUser : users.values()){ userEmail.add(someUser.Email); } } List<String> sendTo = new List<String>(); sendTo.addAll(userEmail); //4. Assign the addresses for the To and CC lists to the mail object. mail.setToAddresses(sendTo); // Specify the subject line for your email address. //5. Set to True if you want to BCC yourself on the email. mail.setBccSender(false); //6.: Set who the email is sent from mail.setReplyTo('noreply@awana.org'); mail.setSenderDisplayName('No Reply'); //7. Set email contents ! mail.setSubject('Accounts Process with Updated or New Account Teams'); String lines = '<br>'; Integer lineCounter = 0; Integer lineLimit = 20; for(Account an_account : accountsToUpdate){ lines = lines+an_account.Mailing_Address_Book__c+', '; lineCounter++; if(lineCounter == lineLimit - 1){ lines = lines+'<br>'; } if(lineCounter == lineLimit){ lineCounter=0; } }//loop system.debug('<<LINES>> '+lines); mail.setHtmlbody('Total Accounts Processed:<b> '+ accountSize+'</b><br>'+lines+'</b><br>'); // Send the email you have created.' '+ emailList.add(mail); Messaging.sendEmail(emailList); } } } ====================== TEAM MEMBER ACCOUNTS.CLS================== public with sharing class TeamMemberAccounts { /* * Method: handleOpportunityInsert * Inputs: List of Accounts which have ownership updates to be matched with their ATMs (Account Team Member) * Purpose: To verify that we will have a State Director whether due to updating the ATM or creating a new one. * SOQL: 1 * DML: 2 */ public class handlerException extends Exception{} /*************************************************************************************************************************************************** Method: handler: Makes sure that Primary Missionaries are assigned as Account Team Memebrs programmatically ****************************************************************************************************************************************************/ public static void handler(List<Account> Accts,List<ID> acctIDS){ List<AccountTeamMember> insert_ATM_FieldDirs = new List<AccountTeamMember>(); List<AccountTeamMember> insert_ATM_WGroupLdrs = new List<AccountTeamMember>(); List<AccountTeamMember> insert_ATM_PMissions = new List<AccountTeamMember>(); List<Id> ownerIDs = new List<Id>(); Boolean foundStateDir = false; // Old ATM Roles must go because we don't know how if these users are still available. List<AccountTeamMember> delete_ATMS = [Select AccountID,UserId,TeamMemberRole from AccountTeamMember WHERE TeamMemberRole in ('Field Director','Work Group Leader','Primary Missionary') and AccountId in : acctIDs]; if(delete_ATMS.size() > 0){ delete delete_ATMS; } system.debug('<<NUMBER OF QUERIES In TOTAL : '+Limits.getLimitQueries()); //For each account selected go and get the Account Team Mebmers while updating the account owner. List<US_Counties__c> uscs = [Select Name,State_Name__c,Field_Director__c, Work_Group_Leader__c, Primary_Missionary__c from US_Counties__c ORDER BY State_Name__c, Name Asc]; Map<String,List<US_Counties__c>> usCounties = new Map<String,List<US_Counties__c>>(); for(US_Counties__c usc : uscs){ if(!usCounties.containsKey(usc.Name)){ usCounties.put(usc.Name,new List<US_Counties__c>()); } usCounties.get(usc.Name).add(usc); } for(Account a: Accts){ if(usCounties.containsKey(a.Physical_County__c)){ for(US_Counties__c a_county : usCounties.get(a.Physical_County__c)){ if(a_county.State_Name__c == a.Physical_State__c){ insert_ATM_FieldDirs.add(new AccountTeamMember(UserId=a_county.Field_Director__c, AccountId=a.Id,TeamMemberRole='Field Director')); insert_ATM_WGroupLdrs.add(new AccountTeamMember(UserId=a_county.Work_Group_Leader__c, AccountId=a.Id,TeamMemberRole='Work Group Leader')); insert_ATM_PMissions.add(new AccountTeamMember(UserId=a_county.Primary_Missionary__c, AccountId=a.Id,TeamMemberRole='Primary Missionary')); ownerIDS.add(a_county.Primary_Missionary__c); break; } } } } //5. Insert all Permission Set Assignments for Account Health Permissionset using Future Method... this is a Setup DML object if(ownerIDs.size() > 0){ accountHealthAccessHandler(ownerIDs); } //6. - Insert All ATMs if(insert_ATM_FieldDirs.size() > 0){ Database.UpsertResult[] lsr = Database.upsert(insert_ATM_FieldDirs,false); } if(insert_ATM_WGroupLdrs.size() > 0){ Database.SaveResult[] lsr = Database.insert(insert_ATM_WGroupLdrs,false); } if(insert_ATM_PMissions.size() > 0){ Database.SaveResult[] lsr = Database.insert(insert_ATM_PMissions,false); } system.debug('ATMS FOR INSERTED State Dirs: '+insert_ATM_FieldDirs); system.debug('ATMS FOR INSERTED Work Group Leaders: '+insert_ATM_WGroupLdrs); system.debug('ATMS FOR INSERTED Primary Missionaries: '+insert_ATM_PMissions); }//Handler 1 /*************************************************************************************************************************************************** Method: handler: VP for US Missionaries handler: Simply adds an ATM team role for VPs ****************************************************************************************************************************************************/ public static void handler(List<Account> newAccts){ system.debug('<<INSIDE VP Of US Missionaries Handler >> '+newAccts); List<AccountTeamMember> insert_ATM_VPs = new List<AccountTeamMember>(); List<GroupMember> vpUser = [Select UserOrGroupId From GroupMember where Group.Name = 'VP of Account Team' limit 1]; for(Account someAccount : newAccts){ insert_ATM_VPs.add(new AccountTeamMember(UserId=vpUser[0].UserOrGroupId, AccountId=someAccount.Id,TeamMemberRole='VP of US Missionaries')); } if(insert_ATM_VPs.size() > 0){ Database.SaveResult[] lsr = Database.insert(insert_ATM_VPs,false); } }// Handler 2 /*************************************************************************************************************************************************** Method: accountHealthAccessHandler: Future Method for Setup DML so that Permission Set Account Health Access can be given to new account members ****************************************************************************************************************************************************/ //@future public static void accountHealthAccessHandler(List<Id> ownerIDs){ PermissionSet pset = [Select Id From PermissionSet where name = 'Account_Health_Access' limit 1]; List<PermissionSetAssignment> account_health_access = new List<PermissionSetAssignment>(); Map<Id,String> filteredOutIDs = new Map<Id,String>(); for(PermissionSetAssignment dupePSAs : [Select AssigneeId from PermissionSetAssignment where PermissionSet.Name ='Account_Health_Access' and AssigneeId in: ownerIDs] ){ filteredOutIDs.put(dupePSAs.AssigneeId,'Account Health Access'); // Strain out unecessary owners if they already have this Health Account Permission. Example: State Director is account owner again replacing Prime Missionary }// Loop system.debug('<< OWNER LIST>> '+ownerIDs); for(Id someOwnerId : ownerIDs){ if('Account Health Access' != filteredOutIDs.get(someOwnerId)){ account_health_access.add(new PermissionSetAssignment(AssigneeId = someOwnerId, PermissionSetId=pset.Id)); } }//Loop system.debug('<< ACCT HEALTH SIZE>> '+account_health_access.size()); if(account_health_access.size() > 0){ insert account_health_access; } } }//Class
Tony Williams 9
I solved this.
- I had to create within the back a limit which would only process 1000 records at a time out of 9K accont records. To compound th issue I had 5 DML statements.
- I then created a batchable job size of 1000 Database.executeBatch(ord , 1000);