Handling Large Batches in Salesforce Without Governor Limit Errors

When creating a large number of accounts and associated contacts in a batch process, you may encounter System.LimitException: Too many DML rows: 10001 due to Salesforce’s governor limits. For example, if you attempt to insert 10,000 accounts, each with 1,000 contacts, the total DML rows exceed Salesforce’s 10,000-row limit for a single transaction. To solve this problem and handle large batches in Salesforce without governor limit errors, you can use different strategies. The main idea is to break down the workload into manageable chunks that respect Salesforce limits.
Question:
I am trying to create a batch process where I generate a specified number of accounts, each having 1,000 associated contacts. When the number of records exceeds Salesforce’s governor limits (e.g., 10,000 DML rows per transaction), I encounter errors like:
- System.LimitException: Too many DML rows: 10001.
- Batchable instance is too big when passing data to another batch in the
finish
method. - Too many queueable jobs added to the queue when invoking
Queueable
jobs in theexecute
method.
Here’s the code I tried:
public class AccountBatchCreator implements Database.Batchable<String> {
private Integer numberOfAccountsToCreate;
public AccountBatchCreator(Integer numberOfAccountsToCreate) {
this.numberOfAccountsToCreate = numberOfAccountsToCreate;
}
public Iterable<String> start(Database.BatchableContext context) {
List<String> accountNames = new List<String>();
for (Integer i = 0; i < numberOfAccountsToCreate; i++) {
accountNames.add('Test Account -- ' + i);
}
return accountNames;
}
public void execute(Database.BatchableContext context, List<String> scope) {
List<Account> accounts = new List<Account>();
for (String accountName : scope) {
accounts.add(new Account(Name = accountName));
}
insert accounts;
List<Contact> contacts = new List<Contact>();
for (Account account : accounts) {
for (Integer i = 0; i < 1000; i++) {
contacts.add(new Contact(
AccountId = account.Id,
AssistantName = 'test contact',
LastName = 'te',
FirstName = 'st'
));
}
}
insert contacts; // This exceeds the governor limits
}
public void finish(Database.BatchableContext context) {
System.debug('Batch processing completed.');
}
}
// Code to execute the batch
Integer numberOfAccountsToCreate = 10;
AccountBatchCreator batch = new AccountBatchCreator(numberOfAccountsToCreate);
Database.executeBatch(batch, 200);
How can I efficiently handle this scenario while avoiding governor limits?
Begin your Salesforce journey with our  Salesforce training in Mumbai, tailored to provide job-ready skills and practical experience through real-world projects. Sign up today for a free demo session!
Answer:
To handle this scenario, you must split the workload into smaller, manageable chunks. Here are a few approaches to solve this problem:
1. Use Multiple Batches
Instead of processing both accounts and contacts in a single batch, you can use a separate batch process for contacts. The first batch creates accounts, and in its finish
method, you invoke a second batch for contacts.
a. Batch for Creating Accounts:
This batch creates the required accounts and initiates the ContactBatchCreator
in its finish
method.
public class AccountBatchCreator implements Database.Batchable<String> {
private Integer numberOfAccountsToCreate;
public AccountBatchCreator(Integer numberOfAccountsToCreate) {
this.numberOfAccountsToCreate = numberOfAccountsToCreate;
}
public Iterable<String> start(Database.BatchableContext context) {
List<String> accountNames = new List<String>();
for (Integer i = 0; i < numberOfAccountsToCreate; i++) {
accountNames.add('Test Account -- ' + i);
}
return accountNames;
}
public void execute(Database.BatchableContext context, List<String> scope) {
List<Account> accounts = new List<Account>();
for (String accountName : scope) {
accounts.add(new Account(Name = accountName));
}
insert accounts;
}
public void finish(Database.BatchableContext context) {
// Start a new batch for creating contacts
Database.executeBatch(new ContactBatchCreator(), 200);
}
}
Explanation:
This batch class generates account names in the start
method and processes them in chunks in the execute
method. Accounts are inserted in the execute
method. In the finish
method, it starts a new batch process (ContactBatchCreator
) to handle contact creation.
b. Batch for Creating Contacts:
This batch processes accounts in smaller chunks and creates contacts without exceeding governor limits.
public class ContactBatchCreator implements Database.Batchable<Account> {
public Iterable<Account> start(Database.BatchableContext context) {
return [SELECT Id FROM Account]; // Fetch all accounts
}
public void execute(Database.BatchableContext context, List<Account> scope) {
List<Contact> contacts = new List<Contact>();
for (Account account : scope) {
for (Integer i = 0; i < 100; i++) { // Reduced contact count per execute
contacts.add(new Contact(
AccountId = account.Id,
AssistantName = 'test contact',
LastName = 'te',
FirstName = 'st'
));
}
}
insert contacts;
}
public void finish(Database.BatchableContext context) {
System.debug('Contact creation completed.');
}
}
Explanation:
This batch fetches accounts from Salesforce in the start
method. In the execute
method, it creates a smaller number of contacts (e.g., 100 per account) to ensure governor limits are not exceeded. It uses the finish
method to log completion or trigger other processes.
2. Use Chained Queueable Classes
Instead of a batch for contacts, you can use a Queueable
class to handle contact creation in smaller chunks. Avoid adding too many Queueable
jobs in a single transaction.
Queueable for Creating Contacts:
public class ContactQueueable implements Queueable {
private List<Account> accounts;
public ContactQueueable(List<Account> accounts) {
this.accounts = accounts;
}
public void execute(QueueableContext context) {
List<Contact> contacts = new List<Contact>();
for (Account account : accounts) {
for (Integer i = 0; i < 100; i++) { // Reduced contact count
contacts.add(new Contact(
AccountId = account.Id,
AssistantName = 'test contact',
LastName = 'te',
FirstName = 'st'
));
}
}
insert contacts;
}
}
Explanation:
This class is used to process accounts passed to it. Contacts are created in smaller chunks (e.g., 100 per account) and inserted in the execute
method. It helps handle large datasets by chaining multiple queueable jobs if necessary.
3. Reduce Contact Volume per Batch Execution
If feasible, reduce the number of contacts created for each account in a single batch execution to stay within limits.
for (Integer i = 0; i < 100; i++) { // Reduced from 1000
contacts.add(new Contact(
AccountId = account.Id,
AssistantName = 'test contact',
LastName = 'te',
FirstName = 'st'
));
}
Explanation:
In this approach, the number of contacts per account is reduced to stay within governor limits. This may result in fewer contacts but avoids exceeding the 10,000 DML rows limit.
Salesforce Training with Real-Time Project Experience in Mumbai
Our Salesforce training program is designed to offer personalized mentorship, comprehensive certification exam preparation, and expert interview coaching to help you stand out in today’s competitive job market. With hands-on project experience, in-depth study materials, and continuous guidance, you’ll build the confidence and skills to excel. By the end of the program, you’ll be fully equipped to earn certifications and demonstrate the practical expertise employers highly value. Start your Salesforce journey with us and unlock exciting career opportunities!
Our Salesforce training in Mumbai provides an immersive learning experience tailored to equip you with the skills needed to thrive in the CRM industry. Covering key domains like Salesforce Admin, Developer, and AI, the program seamlessly blends theoretical knowledge with practical, real-world applications. Through industry-relevant projects and assignments, you’ll gain the expertise to solve complex business challenges using Salesforce solutions. Led by expert instructors, the training sharpens your technical skills and deepens your understanding of the CRM ecosystem.
Take the first step toward a thriving Salesforce career and explore incredible opportunities. Sign up for a FREE Demo session today!