1

I am using batch apex to associate a contact to a case. I will need to compare all the contacts in the system to the cases with a 'new' status. first_name__c and last_name__c are fields on the case. I want to go over every contact and see if there is a match between the first name and last name on a contact and a 'new' case's first_name__c and last_name__c. If there is 1 match, associate the contact and case. If there are 0 matches, create a new contact and associate it to the case. If there are multiple matches, do nothing and the case will have a null contact. I am using the query locator to get the contacts, which could be millions.

I need to have all the contacts in one batch, can I increase the batch size to 50,000,000? This seems like really bad practice.

If I pass in a batch size of 200 for example, will batch #1 finish before batch #2 begins? For example, in every execute I query for cases with status = 'new'. In the first batch, the contact on the case will be null. If I find a contact and case match in the first batch, it is assigned to the case and the status is unchanged (still 'new'). Will this assignment be reflected in the second batch?

1
  • How many "New" Cases will there be? Is it more like 500 or 500,000? May 27, 2014 at 19:36

2 Answers 2

0

On getting your algorithm implemented, the limiting factors are the governor limits so you always have to watch out for those.

For your particular situation this brute force solution - with a query inside the loop so the batch size must be 200 or less - might work:

public Database.QueryLocator start(Database.BatchableContext context) {
    return Database.getQueryLocator([
                select first_name__c, last_name__c
                from Case
                where Status__c = 'new'
                ]);  
    }
}
public void execute(Database.BatchableContext context, List<Case> cases) {
    for (Case c : cases) {
        Contact[] contacts = [
                select Id
                from Contact
                where FirstName = :c.first_name__c and LastName = :c.LastName
                ];
        ...
    }
}

Instead of iterating over every Contact it queries for the matching Contacts.

2
  • i see what you're saying with the dml in the loop, but this has to be bad practice, right?
    – user8560
    May 29, 2014 at 18:28
  • @user8560 It is a bad practice if you do it in a trigger where there could easily be more than 100 objects and so the SOQL queries governor limit could be exceeded with no way to stop the problem. Here it is being done deliberately taking account of the SOQL queries governor limit (that is 200 for asynchronous code like this) to make sure that limit is never exceeded. If you have 1,000 cases and 10 million Contacts, looping over all the Contacts would likely be much more expensive for the platform than letting its database return just the matching Contacts via 1,000 queries done in 5 batches.
    – Keith C
    May 29, 2014 at 18:40
1

Each execute method within a batch operates in a separate transaction context. To say it another way, any changes to the database (DML) within the execute() method in the first chunk of your batch are fully committed by the time the second chunk in your batch is run.

1
  • great, so it sounds like my strategy will work.
    – user8560
    May 28, 2014 at 16:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .