Scripted business rule race conditions - how to avoid?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-05-2017 12:58 AM
The lack of transaction isolation in business rules is resulting in a lot of race conditions in our system, and we're not sure how best to resolve.
As one example - we have a Master:Detail where the status of the master record needs to sometimes change based on the status of one or more detail records. We have a business rule that runs when a detail record is changed that updates the master record, which works correctly under low load.
However even with only a dozen concurrent users we're finding that business rules are running concurrently and writing over the top of each other. Since there's no transaction isolation, we're finding the last rules to save is often running off out of date data.
We're also finding that `GlideRecord.update()` will actually re-create the record if it was deleted in another transaction. Even if a business rule checks to make sure the record exists before it runs, the record may have been deleted by the time the rule commits its changes and its therefore re-created, leaving a lot of users confused why records sometimes mysteriously reappear after deletion.
In other systems I've used, transaction isolation prevents these problems from occurring in the first place. Since this isn't available in ServiceNow, how do developers normally deal with these kinds of issues and prevent race conditions? Are there any tricks or best practices for working around this?

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-05-2017 01:35 AM
The order field is used primary to avoid race conditions among business rules. But how are you checking if the data is deleted or not before allowing the operation?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-05-2017 01:50 AM
In this case it's the same business rule conflicting with itself, so changing the ordering won't help.
For the delete issue - We're effectively just loading the record, making a change, and saving it inside the script. However if the record was deleted halfway through, then it will be re-created by the update() call (instead of failing, which I'd have expected when trying to update a record that has been deleted).

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-05-2017 03:21 AM
There is a valid function available in the GlideRecord which you can try using to validate if the record actually exists in the database before carrying out the operation.
Take a look if that helps
https://www.servicenowguru.com/scripting/client-scripts-scripting/testing-valid-record/

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-05-2017 01:39 AM
And this is the way I have seen few people avoid such conditions
Simultaneous Update Alert - ServiceNow Wiki
I am not sure if there are any other newer ways to deal with such cases.