"Transaction cancelled - maximum number of outbound HTTP requests exceeded"

xMTinkerer
Giga Expert

I got this error after doing a "bunch" of SOAP Message requests. I'm not sure fully how many, but at least 30, but could be more like 100. This article: Transaction Quotas - ServiceNow Wiki pointed me to the log, which had a similar message:

Cancelling transaction #13381 /sys.scripts.do (maximum number of outbound HTTP requests exceeded): Thread Default-thread-14 (admin, E73A95EC4F6231000E9FA88CA310C7BE), after 8032ms


But that Transaction Quota only references a timeout rather than a max number. It looks like the Quota Rule table has two new rules with some new fields:


transactionrules.png


Is there any way to see into this number? Like see which scripts are run often?

6 REPLIES 6

BobbyNow
ServiceNow Employee
ServiceNow Employee

This type of traffic will not be a good user experience for foreground / ui requests.


The new quota limits are there to make sure we maintain a good experience.



In this case you will need to reduce the number of remote calls and run in the background asynchronously.


The preference would be for you to batch the job as much as possible. If the API does not allow for batching there may be some other interesting things you could do. For example, Is it possible to fetch the user names from xMatters in one transaction and then use that information locally to determine which users to insert and which to update? The idea is to get creative with limiting the back and forth. Once you have it as lean as possible you can spawn multiple async jobs to handle the push to xMatters in manageable chunks staying under the 100 connection limit.


Bobby,


  Can you dig up a way to call Scheduled Jobs from a scoped application? I managed to track down this page: http://www.servicenowguru.com/scripting/execute-scheduled-jobs-script/ that sounds promising.


However, it doesn't seem to run in Fuji's scoped apps. Here is the script, with the added "global":


//Execute a scheduled script job


var rec = new GlideRecord('sysauto_script');


rec.get('name', 'My New Scheduled Job - Testing scope');




if (typeof global.SncTriggerSynchronizer != 'undefined')


    SncTriggerSynchronizer.executeNow(rec);


else


    Packages.com.snc.automation.TriggerSynchronizer.executeNow(rec);



Where DELETEME is the name of my Scheduled Job. The output is this:



Evaluator: java.lang.SecurityException: Invalid object in scoped script: [JavaClass com.snc.automation.TriggerSynchronizer]


  Caused by error in script at line 5



  2: var rec = new GlideRecord('sysauto_script');


  3: rec.get('name', 'My New Scheduled Job - Testing scope');


  4:


==> 5: if (typeof global.SncTriggerSynchronizer != 'undefined')


  6: SncTriggerSynchronizer.executeNow(rec);


  7: else


  8: Packages.com.snc.automation.TriggerSynchronizer.executeNow(rec);



Evaluator: java.lang.SecurityException: Invalid object in scoped script: [JavaClass com.snc.automation.TriggerSynchronizer]


  Caused by error in script at line -1


Background message, type:error, message: Invalid object in scoped script: [JavaClass com.snc.automation.TriggerSynchronizer]




I don't think it matters because I'm pretty sure we aren't getting there, but this is my scheduled job:


scheduled.png


xMTinkerer
Giga Expert

The way our SOAP API is set up we can't reduce the number of calls, or at least not enough to get around the quota rules.


However, I believe the Scheduled Jobs will get us around this. I'll have to do a bit more research to confirm how they interact with the quota rules and how we can adapt our script to use these instead. I'll post back with info.


xMTinkerer
Giga Expert

We were able to get around this Quota rule through the use of the "GlideScriptedHierarchicalWorker". For our batch user and group sync, we run a script from arguments from the menu and through a Script Include break up the work into "buckets". Calculations are made to estimate how many total SOAP calls are needed and then creates a worker for each bucket. General usage of this worker follows:



  worker = new GlideScriptedHierarchicalWorker();


  // This is the name of the worker in the sys_progress_worker table.


  worker.setProgressName("My Worker");



  // Instantiate the ScriptInclude and indicate which method to fire


  // The parameters are passed in order, not by name, so the first


  // value of that putMethodArg is not used.


  worker.setScriptIncludeName( 'x_my_scope.' + "myScriptInclude");


  worker.setScriptIncludeMethod( "syncMembership" );


  worker.putMethodArg("record", record );


  worker.putMethodArg("arg2", arg2 );



  worker.setBackground( true );


  worker.start();



  // Push the progressID into an array... not sure what to do with it yet


  workers.push( worker.getProgressID() );