I want to discuss an unexpected difference between two Salesforce entities: the workflow and the trigger. They both exist in the same solution space, but workflows can only do a small subset of what is possible with triggers. It seems that workflows take the most commonly used trigger functionality and completely manage it behind the scenes, attaching an easy-to-use interface that allows non-technical users to easily use them to add custom functionality to their org. Because their abilities are the same, it is natural to believe that they behave the same when executed, but this proves wrong in at least this one case.
The workflow that I am concerned about, of the four kinds of workflows, is the field-update workflow, which is the one that will update field data. Looking at the Triggers and Order of Execution documentation, this update does not happen in the same transaction that triggered the workflow, but rather it spawns an entirely new update transaction, complete with triggers. Think about that for a second. If I manually update an Opportunity record, the before update and after update Opportunity triggers will fire, then the workflow fires. The unexpected part is here, when the field update workflow spawns *another* update operation on Opportunity just to set that field value. This executes the Opportunity triggers an unexpected *second* time.
This recently bit me in the backside. On an Opportunity trigger, when a condition was met, I wanted to create a new record on a related object. The code was simple enough, but for some reason two records were being created instead of just one. After some investigation, I found that there was a field update workflow defined on the Opportunity object that was causing a second update operation to execute after I manually updated it the first time. This made the trigger functionality fire twice, which is definitely not what I wanted.
Knowing the problem, the trick, then, is to find a way to tell a trigger to not execute when a workflow triggered it. Unless I overlooked something, the only way that a workflow and trigger can communicate is by setting a field value that both have access to. In this manner, let’s have the field update workflow also update an extra field in addition to the original field - a Boolean field that we will call “Is Executing Workflow (Internal use only)”. When the value of this field is true, we tell our trigger to not execute its logic. Don’t forget that we will have to set this value back to false when the trigger is done with it, to prepare for the next time the workflow executes. This means that our logic must be restricted to the before trigger, as this is the only time we can easily reset the Boolean field back to false.
This ‘feature’ of field-update workflows was an unexpected surprise to me, so I wanted to share the experience with any other interested developers. In a similar manner, I was recently slapped in the face by a ‘feature’ of roll-up summary fields, which I also want to share with my readers, but that will have to wait for a later post.