You need to sign in to do that
Don't have an account?

Write a future call (async method) to avoid the System Exception Too many DML rows issue
I have a trigger that calls a asynchronous method and it hits the 'Too Many DML rows' exception. Basically the trigger creates a bunch of records in a child table which is used to do statistics. Is there any way that I can create these records at a later date, for instance schedule a job, or write a class to do the creation after the trigger completes.
I had a solution, but it entails in making numerous calls to the asynchrounous method. When I do that, I hit the barrier of 'Too many Future Calls'
So my main question is how can I break the process up so I can load the DML rows into the child table. BTW, the code is already batching the records and I have optimized the code for bulk operation.
Any ideas/help will be appreciated.
Thanks
How many rows are you trying to created or update in the @future async method?
In the Summer '09 release, a limited release feature called Batch Apex is being released. More information here
This feature might solve your problem where you can execute larger scale apex processes in asynchronous fashion. It depends on the requirements and data/processing volumes.
All Answers
How many rows are you trying to created or update in the @future async method?
In the Summer '09 release, a limited release feature called Batch Apex is being released. More information here
This feature might solve your problem where you can execute larger scale apex processes in asynchronous fashion. It depends on the requirements and data/processing volumes.
You can wait for Summer 09 release and use "Batch Apex" (see http://blog.sforce.com/sforce/2009/05/batch-apex-a-powerful-new-functionality-in-summer-09.html) or ask for it as it is in preview mode now or you can use an alternative method for now:
A method for asynchronous mass DML in portions:
The idea is to have the trigger not to execute the business logic but rather to store meta data regarding the update and execute it later in portions smaller or equal to the governor limits using a batch script (see http://gokubi.com/archives/daily-cron-jobs-with-apex).
Let's take a look at an example. Say I have accounts with hundreds of contacts each and I need to update the contacts phone after the account phone changes (not a very realistic example but it clarifies things).
For this I need to create:
a. A utility object which will hold:
1. The update information (in this case the new phone number).
2. A lookup field for the account.
3. A status pick list field with two values: “Done updating contacts” , “Not done updating contacts”.
We will name this object “Account Update Helper” (API name Account_Update_Helper__c).
b. A custom Account_Update_Helper__c lookup field in the Contact object. We will name it “Last Account Update Helper” (API name Last_Account_Update_Helper__c).
When an account phone gets updated the trigger will create a “Account Update Helper” record with:
a. Phone = new account phone.
b. Status = “Not done updating contacts”.
c. Account = the related account.
The batch script will run at the maximum possible frequency and will query the oldest* Account_Update_ Helper__c record with Status = “Not done updating contacts”**.
It will than query for a maximum of 99 related contacts with Last_Account_Update_Helper__c <> current Account_Update_Helper__c *** and update:
a. Phone = “Account_Update_Helper__c.phone
b. Last_Account_Update_Helper__c = current Account_Update_Helper__c Id (so we'll know not to update it in the next batch script execution).
In case there are no more records to update we set Account_Update_Helper__c.Status__c = 'Done updating contacts'.
* Querying the 'oldest' Account_Update_Helper__c insures that when an account gets updated more than once and before all its contacts where updated, the updates will continue in chronological order and most important - the last update will reflect the last account update.
** Filtering results with Status = “Not done updating contacts” guarantees we are only updating contacts related to a Account_Upate_Helper__c which represents contacts which where not yet updated.
*** Setting this filter: Last_Account_Update_Helper__c <> current Account_Update_Helper__c guarantees we only update contacts that where not already updated as a result of an account phone updated represented by the current Account_Update_Helper__c record.
HTH.
The metadata approach sounds interesting, but the "Batch Apex" would be perfect for my needs. I guess I will check with salesforce to see if we can get it turned on in our sandbox so I can do some coding/testing
Thanks for the response and information answer.