Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

Understanding Workflows Set Values

raprohaska
Kilo Guru

I've been working in ServiceNow for a couple years now but my teammates typically dealt with workflow creation. They practice some implementations that I've never understood and would like to clarify. When setting values, many times they will use a timer before the set values activity. I have been building out a new workflow and using set values within it. If the record had been updated thus triggering the next activity in the workflow, the set value will be saved as expected. In my case though, when an approval is given (thus the update is to the related requested approval record) and I have a Set Values activity there after... the update of value is not committed.

Why is this? Is there a way to invoke a save from the Set Values activity that I'm missing? And why does adding the timer do anything to help out the situation. I don't want to add these timers to my workflow and figure there must be another way.

Thanks,

11 REPLIES 11

dave_knight
ServiceNow Employee
ServiceNow Employee

We have hit the same issue I suspect. I need to verify the following theory, but I believe the problem is this. When a workflow executes, it doesn't call a current.update. It relies on the "Workflow Engine" to do that (which is all things "workflow", like business rules, assignment rules, and yes, what we know as workflow). The engine is the wrapper of this entire process, if you will. 

Here is a knowledge article that describes the engine: https://hi.service-now.com/kb_view.do?sysparm_article=KB0538559

Here is the official documentation: https://docs.servicenow.com/bundle/london-application-development/page/script/general-scripting/reference/r_ExecutionOrderScriptsAndEngines.html

Note that when the record being affected by a Set Value activity is the same record which "triggered" the engine to run (it is in the process of being updated by something else, outside of the workflow), the workflow executes in the "Default Workflow Engine" spot in the diagram below. The actual "current.update()" doesn't happen until the Database operation, after all the before business rules and default workflows. It is that operation, performed by the Workflow Engine, not the Workflow, that save the data updated by Set Value into the database.

 

find_real_file.png

Now, when an approval record is updated, it too goes into this Glide Transaction. However, the record in the transaction is the approval, NOT the referenced record. To get to the referenced record, the out-of-the-box logic for an approval has an after business rule that calls a Workflow method to broadcast a "workflow event" to the workflows executing on that referenced record, which is a different record. This "workflow event" will cause the "remote workflow" to execute immediately (pretty sure about this). In other words, it doesn't get a new Glide Transaction. So, the "remote workflow" executes, and the Set Value activity runs, and the value is updated properly in RAM for that remote record, but alas, there is no engine to finish the job and call "current.update()" on the remote record (again, the record referenced by the approval).

I'm confident that is the problem (but let me confirm.)

So how do you work around that? You need to trigger a Glide Transaction on the remote record, instead of triggering the remote workflow directly. At least, that should be one way to do it. There may be a better API for this, but one way to trigger the transaction is to query for the remote record, make no changes, and hit current.update(). That will trigger the engine.

Here is an update after further review. It looks like the "broadcast" of a workflow event, which will startup a workflow, can also trigger a current.update(), depending on the type of broadcast and the result. If the result of the "broadcast" (in the generic sense, as you will see there are a variety of wf event commands, one of which is called boardcast) is EXECUTED or QUEUED, you can trigger a current.update, depending on the type of command. Regardless of the wf event command, if you get an ABORTED, DEFERRED or IGNORED, you will not trigger a current.update.

The following wf event commands will attempt to trigger a current.update on the record being processed by the workflow (regardless of where it is running in a Glide Transaction): BROADCAST, CANCEL_FLOW, HANDLE_EVENT, PRIORITY_EVENT, NUDGE. The following commands will not attempt to trigger a current.update: END_FLOW, KILL_FLOW, INJECT_EVENT, RUN_FLOW.

Need to see what script include functions call which of these commands...