Recursion in triggers occurs when a trigger causes another trigger to fire, resulting in an infinite loop. This can lead to performance issues and can cause the maximum recursion limit to be exceeded.
To avoid recursion in triggers, it’s best to implement a static boolean variable that checks if the trigger is already executing and skips the logic if it is.
Here’s an example that demonstrates how to avoid recursion in triggers:
trigger UpdateContactName on Account (before update) { static boolean isExecuting = false; if (!isExecuting) { isExecuting = true; try { // Trigger logic goes here } finally { isExecuting = false; } } }
In this code, the isExecuting variable is a static boolean variable that is used to check if the trigger is already executing. If the variable is set to false, the trigger logic is executed and the isExecuting variable is set to true to indicate that the trigger is now executing.
The trigger logic is enclosed in a try-finally block, so that the isExecuting variable is set back to false even if an exception is thrown during the execution of the trigger.
This approach ensures that the trigger logic is only executed once, even if another trigger is fired while the first trigger is executing, thus avoiding recursion.
Example: how to avoid recursion in a trigger:
trigger UpdateContactName on Account (before update) { static boolean isExecuting = false; if (!isExecuting) { isExecuting = true; try { for (Account a : Trigger.new) { Account oldAccount = Trigger.oldMap.get(a.Id); if (a.Name != oldAccount.Name) { for (Contact c : [SELECT Id, FirstName, LastName FROM Contact WHERE AccountId = :a.Id]) { c.FirstName = a.Name; c.LastName = oldAccount.Name; update c; } } } } finally { isExecuting = false; } } }
In this example, a static boolean variable isExecuting is used to check if the trigger is already executing. If the variable is set to false, the trigger logic is executed. If it’s set to true, the trigger logic is skipped.
The trigger logic is enclosed in a try-finally block. This ensures that the isExecuting variable is set back to false even if an exception is thrown during the execution of the trigger, avoiding recursion.
In this case, the trigger logic updates the FirstName and LastName fields of all contacts associated with an account if the account’s name has changed. The trigger logic is executed only once, even if another trigger is fired while the first trigger is executing.