+ Start a Discussion
Denis VakulishinDenis Vakulishin 

Trigger executes twice

Hi,
I have a trigger on Opportunity and it creates child objects after closing the Opp, but there's a rare problem which results wrong logic workflow - trigger logic executes twice. Furthermore, it executes with the same values in Trigger.new and Trigger.old(I have field difference check in trigger). I don't know the original cause of it, maybe it's because browser sends request twice due to network problems.
Now I implemented 2 workarounds:
1) Added static boolean to the handler class and check it before firing logic
2) Added locking the OPP. It's updating after creaton of child objects

So, can enyone suggets more solutions for this problems?

Thanks.
Denis VakulishinDenis Vakulishin
trigger OpportunityTrigger on Opportunity (after update) 
{
   
   Set<Id> setCWOppies = new Set<id>();
         
   for(Opportunity newOpp : Trigger.new)
   {
   	Opportunity oldOpp = Trigger.oldMap.get(newOpp.Id);
      
          
      //If OPP CW         
      if(newOpp.StageName == OpportunityHandler.OPP_STAGE_CLOSED_WON && 
         newOpp.StageName != oldOpp.StageName && 
         newOpp.CloseDate == Date.Today())
      {
            setCWOppies.add(newOpp.Id);
      }
   }
   
   if(setCWSuccess.size() > 0)
   {
   	//Creating some child objects

   	//Call @future method with callout=true
        //In Apex Jobs log there're 2 calls with the same time
   }
}
Ankit AroraAnkit Arora
If the child is in master-detail relationship then once child is created parent is updated (due to rollup etc..) so that might be the cause of twice trigger execution. You've already implemented the workarounds so that's good. Also if the case is, trigger should only fire when opportunity is closing then you can use that condition in trigger and check it in start if value of stage is chaning and it's becoming close (closed/won or closed/lost whatever it is) then only the rest logic will fire.

Let me know if that works.
Denis VakulishinDenis Vakulishin
No there're no maser-detail relationship, but I update Opportunity directly from code. The main problem is that normally I cannot reproduce this. Yesterday I go further and wrote simple WinForms client(oAuth) which closes the same Opp in 2-4 parallel threads, but this testing had no success. There's still only one trigger execution.
In PROD organization this issue happened only twice(at least during this 7 months).

About checking "closed-won, closed-lost..." : In the example above I've already implemented this. For the bulkification of logic I collect Opps Ids and later in the end of the example I use only this Ids.

This kind of rare bug which VERY hard to reproduce(I still cannot reproduce it in normal way, without developer console).