7

We've an inbound web service which is inserting/updating 1000s of records at a time. We've trigger which fires on update, but we noticed, it is 'only' firing for first 200 records at a time and skipping rest.

For e.g 1000 records are sent by external service, then trigger gets executed only for first 200, rest 800 are getting skipped.

On further analysis we found, that our static variable to prevent 'multiple' trigger execution in same transaction is getting 'set', after update of first 200 records, and because of that, trigger doesn't get executed for remaining records.

This surprised us and we find something similar mentioned in this thread :

Bulk API and Static Variable State

I'm still having trouble in understanding above thread. This mentions that static variable are not 'set' for BULK API. In our case, this is just SOAP API which is inserting/updating 1000s of records. so my first question :

Q1 How different is bulk API w.r.t to SOAP API when 1000 records are getting inserted as far as handling static variables are concerned? As far as I know, in both cases, records will be implicitly broken into batch of 200 records , so if static variable is 'set' from false to true after first 200 records, then in both case, execution of code dependent on that static variable, would stop for next 200 records execution and so-on. Is that correct ?

Q2 I decided not to make my code dependent on static variable. So I've removed them and able to put other conditions for now to prevent multiple execution of same trigger( for e.g only on change of value, it fires) But I'm not finding it is not 100% fool proof as other developers in future could write code that could get executed multiple times(giving rise to 100 SOQL error etc) in absence of static variable. Is there any thing else I could do in my trigger ?

Q3 I'm thinking to make change in my inbound web service class itself which accepts list of records (could be in 1000s) .I'm thinking to devide, say 1000 records into batches of 200 records and call 'future' method to process them but problem is we've to send response back to service calling our inbound webservice . Using future then won't be an option. What other options I've to make change in the webservice class ?

Thanks for any direction in this regard.

  • 1
    FYI, where you have ID values available, you can use a Set<Id> instead of a single Boolean to guard against multiple invocations of logic in a trigger. – Keith C Nov 13 '15 at 8:52
3

The basic solution in the Knowledge Article How to avoid Recursive trigger uses a static Boolean variable to indicate if the trigger has run once. When the trigger is run again in the same execution context it is then bypassed.

As you have found, when performing DML on multiple records they will be passed into the triggers in batches of 200. As such, your trigger will be called for each subset of 200 records within the same execution context and will share the same static variables.

If you have a unique field on the object you can switch out the static Boolean for a static Set<uniqueKeyType> with the correct type for the unique key. Then check each record against this set and only proceed to process it if it hasn't already been visited.

If you are only dealing with update triggers then you can use a Set of Id.

This approach should scale well. It can also make test cases easier as you can remove records from the internal set if you want the trigger to fire again. Or add them if you don't want it to fire.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.